Javascript.RU

Создать новую тему Ответ
 
Опции темы Искать в теме
  #71 (permalink)  
Старый 18.04.2009, 00:12
...
Отправить личное сообщение для Zeroglif Посмотреть профиль Найти все сообщения от Zeroglif
 
Регистрация: 09.03.2008
Сообщений: 216

Сообщение от kefi
и вуа-ля - спокойно используем, надежно зная и понимая , какие значения будут у переменных
Так и есть, вы в своём примере даже не выходите из контекстов (рекурсия не в счёт), а раз вы там внутри находитесь, то имеете полное право менять значения 'a' и 'b', и тем более 'g' из любого места, откуда доступны эти свойства. Вот если вы из функции 'A' выйдете и начнёте работать с замыканием снаружи, то кроме него (замыкания) никто ничего не поменяет...
Ответить с цитированием
  #72 (permalink)  
Старый 18.04.2009, 01:16
Кандидат Javascript-наук
Отправить личное сообщение для kefi Посмотреть профиль Найти все сообщения от kefi
 
Регистрация: 12.03.2009
Сообщений: 148

Цитата:
Так и есть, вы в своём примере даже не выходите из контекстов (рекурсия не в счёт), а раз вы там внутри находитесь, то имеете полное право менять значения 'a' и 'b', и тем более 'g' из любого места, откуда доступны эти свойства. Вот если вы из функции 'A' выйдете и начнёте работать с замыканием снаружи,
то-то и оно , что не так и есть
Т.е. для b - это не так , не из любого места ( см пример для B(1); ) и выхожу я в примере ( частично ) из контекста Замыкания.
Ответить с цитированием
  #73 (permalink)  
Старый 18.04.2009, 01:46
Профессор
Отправить личное сообщение для Dmitry A. Soshnikov Посмотреть профиль Найти все сообщения от Dmitry A. Soshnikov
 
Регистрация: 25.02.2008
Сообщений: 707

kefi, Вы что-то больше себя путаете, толком сами не определились, что хотите спросить (и что конкретно не понятно). Не надо подобных примеров с тучей комментарием, тучей переменных и т.д. Если хотите что-то понять, и осознать (и чтобы легко запоминалось) - надо делать это на примерах с "a" и "b" - не более.

Сообщение от kefi
Так вроде я сам предложил объяснение.
Замечательно, но старайтесь не выдумывать.

Сообщение от kefi
как только замкнули (myScope = C)
Я ж выше писал, что это просто ссылка, а не замыкание (замыкание уже произошло - и это "C"). Зачем Вы продолжаете себя запутывать?

Сообщение от kefi
Я просил для практического руководства
Ну так и нужно стараться понимать

Сообщение от kefi
чтобы легко запомнить и одновременно предельно ясные
Давайте так, на очень кратком примере Вы описываете, что не ясно, а мы постараемся очень по-простому объяснить.

P.S.:

Сообщение от kefi
[[VO]]
Тоже лучше не миксовать обозначения. Когда писалось [[Scope]] - это реальное обозначение из стандарта. Обозначая таким же образом VO, Вы можете сбить с толку тех, кто будет это читать и не знать пока про VO.
__________________
Тонкости ECMAScript

Последний раз редактировалось Dmitry A. Soshnikov, 18.04.2009 в 11:06.
Ответить с цитированием
  #74 (permalink)  
Старый 18.04.2009, 09:06
...
Отправить личное сообщение для Zeroglif Посмотреть профиль Найти все сообщения от Zeroglif
 
Регистрация: 09.03.2008
Сообщений: 216

Сообщение от kefi
для b - это не так , не из любого места
Так, так. Функция 'B' видит тот же самый объект, что и функция 'C' - VO(A), т.к. обе функции имеют этот объект в своей scope chain. Поэтому изменение значения переменной 'a' будет отражено. И, наоборот, изменение значения переменной 'b' не видно 'C', т.к. у неё совсем другой объект в scope chain - VO(B) от первого вызова 'B', а 'b' меняется в VO(B) от второго вызова...
Ответить с цитированием
  #75 (permalink)  
Старый 18.04.2009, 11:12
Интересующийся
Отправить личное сообщение для Артем Шалхаков Посмотреть профиль Найти все сообщения от Артем Шалхаков
 
Регистрация: 07.04.2009
Сообщений: 24

Все-таки жесть этот JavaScript.

Нужна лексическая область видимости -- юзайте лексическую, нужна динамическая -- используйте ее, опять же.

А тут смешали бензин с кошачьим дерьмом, надеясь получить взрывную смесь, а получили... бензин с кошачьим дерьмом вперемешку.

Пусть дан такой кодец:

var x = 0;
var f = function() { return x; }
var g = function() { var x = 1; return f(); }


Если область видимости динамическая, то g вернет 1, а если лексическая -- то 0. И не нужные никакие activation objects, [[SCOPE]] и прочая муть.

Читать: http://en.wikipedia.org/wiki/Scope_(programming) или SICP, там отличные примеры.

Ну и конкретно по JS: http://www.digital-web.com/articles/...in_javascript/
Ответить с цитированием
  #76 (permalink)  
Старый 18.04.2009, 12:30
Профессор
Отправить личное сообщение для Dmitry A. Soshnikov Посмотреть профиль Найти все сообщения от Dmitry A. Soshnikov
 
Регистрация: 25.02.2008
Сообщений: 707

Сообщение от Артем Шалхаков
Если область видимости динамическая, то g вернет 1, а если лексическая -- то 0.
Тогда, относительно этих определений, я смиксовал/напутал, и [[Scope]] JS можно отнести к lexical (static) scope, поскольку [[Scope]] однозначно зашился в функцию при её создании, и именно в нём будет искаться "x".
__________________
Тонкости ECMAScript
Ответить с цитированием
  #77 (permalink)  
Старый 18.04.2009, 13:47
Кандидат Javascript-наук
Отправить личное сообщение для kefi Посмотреть профиль Найти все сообщения от kefi
 
Регистрация: 12.03.2009
Сообщений: 148

Сообщение от Zeroglif
Так, так.
Не так не так, так так. Уже запутались. Вы, видимо , правильно понимаете, но то, что говорил я не поняли. Спасибо за пример с EVAL, который я сразу не заметил. Он кстати показал мне , что СКОП замыкания не может получить новые слоты после Замыкания, т.е. вообще говоря Замыкания могут общаться через свои Скопы Замыкания, если они пересекаются, НО вот нельзя с помощью EVAL взять и добавить новые переменные в СкопЗамыкания.


Сообщение от Dmitry A. Soshnikov
как только замкнули (myScope = C)
Я ж выше писал, что это просто ссылка, а не замыкание (замыкание уже произошло - и это "C"). Зачем Вы продолжаете себя запутывать?
До этих Ваших слов (что я выделил ) мне было все ясно. Но вот они действительно меня запутывают. Мне так хорошо все понималось, когда я считал , что замыкание это процесс присвоения ссылки на FE (myScope = C) переменной или ,точнее , просто использование имени Замыкаемой функции в выражении, и саму такую переменную-ссылку я тоже называл Замыканием.
Цитата:
Не надо подобных примеров с тучей комментарием, тучей переменных и т.д.
Да и я бы не хотел, но в этом примере нет ни одной лишней ни функции ни переменной(пардон за одну лишнюю c - да и она оставлена, так сказать, для размножения), иначе смысл того, что хотел сказать теряется.

Цитата:
[[VO]]
Тоже лучше не миксовать обозначения. Когда писалось [[Scope]] - это реальное обозначение из стандарта.
VO - это тоже понятие стандарта, обозначающее, кстати внутренний объект такой же как и остальные обозначенные там через [[...]], а почему оно там не обозначено в [[...]], как остальные внутренние объекты, - не знаю.

Сообщение от Артем Шалхаков
А тут смешали бензин с кошачьим дерьмом, надеясь получить взрывную смесь,
Так , а что собственно Вам в данном вопросе напомнило бензин с кошачьим дерьмом вместо взрывной смеси ?
И , Кстати, причем здесь взрывная смесь? Без Замыканий при использовании функций в качестве переменных логически невозможно обойтись , даже если Вы не нуждаетесь ни в какой взрывной смеси.

Последний раз редактировалось kefi, 18.04.2009 в 14:28.
Ответить с цитированием
  #78 (permalink)  
Старый 18.04.2009, 14:35
...
Отправить личное сообщение для Zeroglif Посмотреть профиль Найти все сообщения от Zeroglif
 
Регистрация: 09.03.2008
Сообщений: 216

Сообщение от kefi
но то, что говорил я не поняли
Честно пытался. Вы сказали: "для b - это не так , не из любого места", поясните подробнее, что сломалось (что не нравится), попробую понять, а то вы препарируете стандарт в свой собственный язык, остаётся только догадываться, про что речь. Вот это не понятно:

"Замыкания могут общаться через свои Скопы Замыкания"


и это:

"...с частичным выходом из Контекста Замыкания"

и уж тем более:

"Программма всегда может получить доступ ко всему [[Scope]]'у' Замыкания передав управление в Замкнутую функцию ЧЕРЕЗ Замыкание."


p.s. и первый, и второй пример - совершенно обычные по своему поведению, всё абсолютно в рамках логики языка, немного усложнено рекурсией, но это ничего не меняет в схеме создания scope chain и в схеме разрешения идентификаторов.
Ответить с цитированием
  #79 (permalink)  
Старый 18.04.2009, 15:22
Кандидат Javascript-наук
Отправить личное сообщение для kefi Посмотреть профиль Найти все сообщения от kefi
 
Регистрация: 12.03.2009
Сообщений: 148

Сообщение от Zeroglif
что сломалось (что не нравится),
А где я сказал, что что-то сломалось или мне не нравится ?
1)
Цитата:
"Программма всегда может получить доступ ко всему [[Scope]]'у' Замыкания передав управление в Замкнутую функцию ЧЕРЕЗ Замыкание."
Выделенное означает вызов Замкнутой функции через Замыкание :
т.е. myScope(), а не через C().

Цитата:
"Замыкания могут общаться через свои Скопы Замыкания"
Цитата:
"...с частичным выходом из Контекста Замыкания"
А это вообще становится понятным , если прочитать определения , которые я дал в том посте.
Повторю их немного яснее.
/* Более корректное Уточнение Замыкания .
Замыкание - установка Защитника(Телохранителя) для Скопа Замыкания(см ниже). Пока он живой или пока живы те, кому его
скопировали, СкопЗамыкания не убить. Защитником является переменная Замыкания (или просто 'Замыкание'), т.е. ссылка
на замыкаемую функцию (переменная или фактический параметр).
Установить Замыкание (Замкнуть) - можно ТОЛЬКО на Уровне(см ниже Уровни) Контекста Замыкания и вложенных. Установить -
значит присвоить с помощью FE ссылку на функцию переменной или, точнее, просто использовать Имя Замыкаемой функции в выражении .

Когда Программа может менять слоты [[Scope]]'a' Замыкания (основная проблема анализа Замыканий):

[[Scope]] Замыкания - [[Scope]] замыкаемой функции. Он Живой пока живой его Защитник ссылка на Замыкаемую функцию.
Контекст Замыкания - Весь Внешний контекст Замыкаемой функции, т.е. Весь Контекст в который она вложена.
Все вызовы через Замыкание происходят с использованием [[Scope]]-а Замыкания для определения в вызываемой функции
значений свободных переменных, точнее слотов [[Scope]]'а Замыкания .

Уровни Контекста - Верхний(0 или Global),Первый(1 или функций Верхнего уровня(А функций)), Второй(2 или B) , etc ...
( Уровнем Контекста Замыкания считается не Global,а Уровень контекста Замыкаемой функции. )

В случае выхода управления на Верхний уровень Программе оказываются доступными только слоты
[[Scope]]'а' Замыкания для [[Scope Chain]]'а' этого уровня, т.е. только [[VO]]Global.

Если управление выходит из Контекста Замыкания не полностью на Верхний Уровень, а на какой-то его Уровень ниже,
то Программе на этом Уровне становятся доступными ТОЛЬКО слоты [[Scope]]'а' Замыкания для [[Scope Chain]]'а'
этого Уровня , При дальнейшем входе с этого Уровня на Вложенные уровни, вновь создаваемые [[VO]] вложенных уровней
ЗАКРЫВАЮТ(консервируют) сответствующие [[VO]] для этих уровней из [[Scope]]'а' Замыкания.

Программа всегда может получить доступ ко всему [[Scope]]'у' Замыкания, передав управление в Замкнутую функцию
ЧЕРЕЗ Замыкание.

Разные Замыкания могут общаться через пересекающиеся слоты своих СкоповЗамыкания.
*/
function al(o){document.write(o,'<br>')} ;
al('g,a,b,c ---------------');
var myScope , g = 0 , myScope2 ;
A();
function A(x) { // Вход сюда создает новый [[VO]]A ,но не затрагивает [[VO]]Global === ( [[Scope]]A == [ myScope, g==0 ] )
    var a;
    if (x==1) { a=2; b=2; c=2; al( [g, a, b, c, '<---A( )'] );  myScope(2) ; return  } ; 
    if (x==2) { al( [g, a, b, c, '-- имеем в A( )']); return  } ; 
    myScope2=B;
    B(); 
    function B(y,e,e1) { // Вход сюда создает новый [[VO]]B ,но не затрагивает [[VO]]А,[[VO]]Global 
        var b;
        if (y==1) { a=3; b=3; c=3; eval(e); al( [g, a, b, c,eval(e1) , '<---B( )']); myScope(2); return  } ; 
        if (y==2) { al( [g, a, b, c,eval(e1),  '-- имеем в B( )']); return  } ; 
        C();
        function C(z,e,e1) { // Вход сюда создает новый [[VO]]С ,но не затрагивает [[VO]]B, [[VO]]А ,[[VO]]Global 
            var c; 
            if (z==1) { a=4; b=4; c=4; al( [g, a, b, c,eval(e1), '<---C( )']); myScope(2); return  } ; 
            if (z==2) { al( [g, a, b, c, eval(e1), '-- имеем в C( )']); return  } ; 
            
            // myScope = B ; // [[Scope]]B == [ myScope, g==0,a==1,x, B ]
            // Замкнуть, Контекстом Замыкания будет весь Внешний Контекст функции C :
            myScope = C ; 
            // [[Scope]] Замыкания  [[Scope]]C == [ myScope, g==0,a==1,b==1, x, y, B, C ]
            // g,a,b,c ---------------
            // 0,,,,-- имеем в C( ) // <-исходное состояние [[Scope]]'а' Замыкания
            myScope(2);
            
            // Выход на уровень Контекста Global - Полный выход из Контекста Замыкания, В вызываемой функции A
            // никакие слоты [[Scope]]'a' Замыкания не доступны, кроме [[Scope]]A === [[VO]]Global слотов  (ни а ни b не изменить)
            // 0,2,2,2,<---A( )
            // 0,,,,-- имеем в C( )
            A(1); 
            
            // Выход на Уровень Контекста А - Частичный выход из Контекста Замыкания,
            // в вызываемой B() будут доступны только слоты [[Scope]]'a' Замыкания для [[Scope]]B ( a можем изменить, b -нет )
            // 0,3,3,3,<---B( )
            // 0,3,,,-- имеем в C( )  // 0,3,3,1,-- имеем в C( ) для вызова C(2) вместо myScope(2),т.е. b меняем !
            B(1);   
            
            // Выход на уровень Контекста B, Нет выхода из Конекста Замыкания, 
            // в вызываемой  С() будут доступны все слоты [[Scope]]'a' Замыкания для [[Scope]]C (a и b можно изменить)
            C(1);   
            // 0,4,4,4,<---C( )
            // 0,4,4,,-- имеем в C( )
            return; // Выход на уровень Контекста B            
        };
        return ; // Выход на уровень Контекста A
	};
    return ; // Выход на уровень Контекста Global - Полный выход из Контекста Замыкания  
};
al('-----------Как Разные Замыкания могут общаться через пересекающиеся слоты своих СкоповЗамыкания. ---------------------');
al([g,a,b,c,'--имеем в Global как нагрузку от некоторых первичных присваиваний во внутренних функциях ']); // 0,4,2,3,--имеем в Global
myScope2(2); // 0,4,,3,-- имеем в B( ) - в СкопеЗамыкания B имеем тот же a , что и 
myScope(2);  // 0,4,4,,-- имеем в C( )   в СкопеЗамыкания C (но переменной b из СкопаЗамыкания С в СкопеЗамыкания B нет)
myScope2(1,'var ee=11'); // 0,3,3,3,<---B( )
             // 0,3,4,,-- имеем в C( )
//myScope(2,1,'ee'); // ee НЕ ОПРЕДЕЛЕН в C !!! EVAL не меняет слоты Контекста Замыкания !

al([g,a,b,c,'--имеем в Global как нагрузку от некоторых первичных присваиваний во внутренних функциях ']); // 0,4,2,3,--имеем в Global

Последний раз редактировалось kefi, 18.04.2009 в 15:32.
Ответить с цитированием
  #80 (permalink)  
Старый 18.04.2009, 15:51
...
Отправить личное сообщение для Zeroglif Посмотреть профиль Найти все сообщения от Zeroglif
 
Регистрация: 09.03.2008
Сообщений: 216

Сообщение от kefi
Повторю их немного яснее.


Вы упорно пытаетесь перевести общепринятую логику стандарта на птичий язык ньюба, где происходит "установка Защитника(Телохранителя)", где этим "Защитником является переменная Замыкания", где происходит некий "частичный выход из Контекста Замыкания" и так далее. Предположу, что эти ассоциации помогают вам вникать в суть вещей, но повторюсь - примеры простейшие, никаких в них нет странностей, сверхъестественного, начните, наконец, изучать стандарт и стараться разговаривать на его языке. Что ж мы воду толчём в ступе...
Ответить с цитированием
Ответ



Опции темы Искать в теме
Искать в теме:

Расширенный поиск