Javascript.RU

Создать новую тему Ответ
 
Опции темы Искать в теме
  #61 (permalink)  
Старый 17.04.2009, 00:25
Кандидат Javascript-наук
Отправить личное сообщение для kefi Посмотреть профиль Найти все сообщения от kefi
 
Регистрация: 12.03.2009
Сообщений: 148

Сообщение от Dmitry A. Soshnikov
это динамическая цепь (есть ещё и статическая
Чем дальше в сказку, тем страшнее ...

Цитата:
Найденное в Scope chain значение, всегда будет последним присвоенным (связанным) значением этой переменной. Чтобы это предотвратить (а такие случаи бывают нужны - например, при замыкании счетчика цикла) - создают новую функцию с новым VO - т.е. передают нужное значение (счетчик цикла) параметром в создаваемую функцию.
Не понял, к чему это здесь ?..

Цитата:
Зачем Здесь хранить Scope Chain (b)
Ну а как? - в "d" есть свободные переменные.
Ну и пусть есть , ведь далее при повторном вызове savB(); // 40
из того же контекста где эти переменные известны мы же однозначно их определяем ?..

Впрочем, вот сам опровергну свои слова, хотя не понимаю, зачем так сделано :
var a = 10;
function b(x) {
  var c = 20; 
  // Здесь пытаемся вызвать из контекста b, в котором однозначно какзалось бы определяются все значения VO(b)
  if (x) { a=5; c=7; x(); return  } ; // 30,0,5 <- НИКАКОГО влияния нового c==7 ! осталось старое законсервированное c==0
  function d() {
    var e = 30;   al( [e ,c , a ]);
  };
  // Замыкаем на savB
  var savB=d; // Scope Chain (b) === [[Scope]](d)    Зачем Здесь хранить Scope Chain (b)  ?
  savB(); // 30,20,10
  c=0;    // Если бы VO(b) законсервировался при замыкании, то это изменение 
          // НЕ оказало бы воздействия на последующий вызов через Замыкание: 
  savB(); // 30,0,10  <- Scope Chain (b), т.е. VO(b) - не законсервировался, т.к.
          // здесь вызов почувствовал (?) изменение с с=20 на --> c=0 
          // НО ПОЧЕМУ ????????????????? ЗДЕСЬ [[Scope]](d) НЕ СОХРАНИЛСЯ 
  b(savB); // 30,0,5 <- А вот так НЕ почувствовал с=7 , хотя контекст b, казалось бы мог сам определить свои значения, Караул !!!
  return savB;
};
var s=b(); 
//s();      // 30,0,10 <- Scope Chain (b), т.е. VO(b) - Законсервировался, но Global - нет.
// b(s);     // 30,0,5
s();      // 30,0,5


Но уж Global'то VO - никогда не консервируется при замыканиях ?!

PS. Можно еще пояснить вопрос НО ПОЧЕМУ?????????? в примере ?
Просто я считал, что
Замыкание необходимо для разрешения неоднозначности значений локальных переменных из [[Scope]] замыкаемой функции, которая возникает , если ссылка на функцию сохраняется вне Контекста охватывающей функции и мы захотим вызвать функцию Извне ее Охватывающего Контекста по этой ссылке.

Последний раз редактировалось kefi, 17.04.2009 в 00:41.
Ответить с цитированием
  #62 (permalink)  
Старый 17.04.2009, 08:16
...
Отправить личное сообщение для Zeroglif Посмотреть профиль Найти все сообщения от Zeroglif
 
Регистрация: 09.03.2008
Сообщений: 216

Сообщение от kefi
НО ПОЧЕМУ ?????????????????
Funarg, етить его... Функция "запоминает" [[Scope]] (все вышестоящие VO) в момент создания, один раз и навсегда. Дальше уже не имеет значения, куда эту функцию засовывают. Отсюда, если при создании функции 'd', её статичный [[Scope]] - это VO(b)->VO(global), то это уже не изменится, единственное, что динамично - это создание собственного VO(d), что происходит в любой функции с каждым вызовом.

Когда вы отправляете функцию 'd' в качестве аргумента, то у функции 'b' создаётся собственный новый VO(b), но 'd' это не волнует, т.к. неё другой VO(b), созданный ранее при первом вызове. Соответственно, свойство 'c' одного объекта не имеет никакого отношения к свойству 'c' другого объекта...

Последний раз редактировалось Zeroglif, 17.04.2009 в 08:18.
Ответить с цитированием
  #63 (permalink)  
Старый 17.04.2009, 11:41
Профессор
Отправить личное сообщение для Dmitry A. Soshnikov Посмотреть профиль Найти все сообщения от Dmitry A. Soshnikov
 
Регистрация: 25.02.2008
Сообщений: 707

Сообщение от kefi
Не понял, к чему это здесь ?..
К тому, что на момент, пока существует воздействие на живой вышестоящий VO, найденное значение свойства в этом VO будет последним присвоенным значением. А вот, когда уже функция передаётся параметром, у "вышестоящей" функции уже другой VO (вот в этом моменте можно говорить о "консервировании" [[Scope]] в функции, но только при условии, что вышестоящий VO уже новый/не существует старый).
__________________
Тонкости ECMAScript

Последний раз редактировалось Dmitry A. Soshnikov, 17.04.2009 в 15:08.
Ответить с цитированием
  #64 (permalink)  
Старый 17.04.2009, 20:03
Кандидат Javascript-наук
Отправить личное сообщение для kefi Посмотреть профиль Найти все сообщения от kefi
 
Регистрация: 12.03.2009
Сообщений: 148

Все правильно сказано, но вот что-то не достает для практического руководства, т.е. нужны какие-то
краткие , чтобы легко запомнить и одновременно предельно ясные, чтобы не ошибиться слова ,
поясняющие явление Замыкания.
У меня вот тоже не очень получается сложить такие слова.
попытался вот так, исправьте,плз, что не так :

/* Когда Программа может менять слоты [[Scope]]'a' Замыкания :

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

В случае выхода управления на Верхний уровень Программе оказываются доступными только слоты
[[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 ;
A();
function A(x) { // Вход сюда создает новый [[VO]]A ,но не затрагивает [[VO]]Global === ( [[Scope]]A == [ myScope, g==0 ] )
    var a = 1; 
    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  } ; 
    B();
    function B(y) { // Вход сюда создает новый [[VO]]B ,но не затрагивает [[VO]]А,[[VO]]Global 
      var b = 1;
        if (y==1) { a=3; b=3; c=3; al( [g, a, b, c, '<---B( )']); myScope(2); return  } ; 
        if (y==2) { al( [g, a, b, c,  '-- имеем в B( )']); return  } ; 
        C();
        function C(z) { // Вход сюда создает новый [[VO]]С ,но не затрагивает [[VO]]B, [[VO]]А ,[[VO]]Global 
            var c=1;
            if (z==1) { a=4; b=4; c=4; al( [g, a, b, c, '<---C( )']); myScope(2); return  } ; 
            if (z==2) { al( [g, a, b, c, '-- имеем в 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,1,1,1,-- имеем в C( ) // <-исходное состояние [[Scope]]'а' Замыкания
            myScope(2);
            
            // Выход на уровень Контекста Global - Полный выход из Контекста Замыкания, В вызываемой функции A
            // никакие слоты [[Scope]]'a' Замыкания не доступны, кроме [[Scope]]A === [[VO]]Global слотов  (ни а ни b не изменить)
            // 0,2,2,2,<---A( )
            // 0,1,1,1,-- имеем в C( )
            A(1); 
            
            // Выход на Уровень Контекста А - Частичный выход из Контекста Замыкания,
            // в вызываемой B() будут доступны только слоты [[Scope]]'a' Замыкания для [[Scope]]B ( a можем изменить, b -нет )
            // 0,3,3,3,<---B( )
            // 0,3,1,1,-- имеем в C( )  // 0,3,3,1,-- имеем в C( ) для вызова C(2) вместо myScope(2),т.е. b меняем !
            B(1);   
            
            // Выход на уровень Контекста B, Нет выхода из Конекста Замыкания, 
            // в вызываемой  С() будут доступны все слоты [[Scope]]'a' Замыкания для [[Scope]]C (a и b можно изменить)
            C(1);   
            return; // Выход на уровень Контекста B
            // 0,4,4,4,<---C( )
            // 0,4,4,1,-- имеем в C( )
            
        };
        return ; // Выход на уровень Контекста A
     };
    return ; // Выход на уровень Контекста Global - Полный выход из Контекста Замыкания  
};

Последний раз редактировалось kefi, 17.04.2009 в 23:34.
Ответить с цитированием
  #65 (permalink)  
Старый 17.04.2009, 20:45
...
Отправить личное сообщение для Zeroglif Посмотреть профиль Найти все сообщения от Zeroglif
 
Регистрация: 09.03.2008
Сообщений: 216

Сообщение от kefi
исправьте,плз, что не так
Всё не так. Аццкий текст.
Ответить с цитированием
  #66 (permalink)  
Старый 17.04.2009, 21:32
Кандидат Javascript-наук
Отправить личное сообщение для kefi Посмотреть профиль Найти все сообщения от kefi
 
Регистрация: 12.03.2009
Сообщений: 148

Сообщение от Zeroglif
Всё не так.
Так все не так не бувает. Объясните то, что иллюстрировано примером, чтобы было легко запомнить и одновременно предельно ясно.

Последний раз редактировалось kefi, 17.04.2009 в 21:36.
Ответить с цитированием
  #67 (permalink)  
Старый 17.04.2009, 21:59
Профессор
Отправить личное сообщение для Dmitry A. Soshnikov Посмотреть профиль Найти все сообщения от Dmitry A. Soshnikov
 
Регистрация: 25.02.2008
Сообщений: 707

Сообщение от kefi
поясняющие явление Замыкания.
Замыкание - это...
__________________
Тонкости ECMAScript
Ответить с цитированием
  #68 (permalink)  
Старый 17.04.2009, 23:04
...
Отправить личное сообщение для Zeroglif Посмотреть профиль Найти все сообщения от Zeroglif
 
Регистрация: 09.03.2008
Сообщений: 216

Сообщение от kefi
Объясните то, что иллюстрировано примером
Давайте вы спросите, что именно не понятно, а я попробую объяснить. Или не я. Чтобы не писать одно и то же и не расшифровывать примеры.
Ответить с цитированием
  #69 (permalink)  
Старый 17.04.2009, 23:29
Кандидат Javascript-наук
Отправить личное сообщение для kefi Посмотреть профиль Найти все сообщения от kefi
 
Регистрация: 12.03.2009
Сообщений: 148

Цитата:
Замыкание - это...
Я просил для практического руководства, т.е. нужны какие-то
краткие , чтобы легко запомнить и одновременно предельно ясные, чтобы не ошибиться слова, и потом, не совсем про то, что такое Замыкание, а про ... см ниже

Цитата:
Давайте вы спросите, что именно не понятно, а я попробую объяснить Или не я. Чтобы не писать одно и то же и не расшифровывать примеры.
Так вроде я сам предложил объяснение.
Мне кажется Дело бы при Замыканиях было бы довольно просто , если бы [[Scope]]Замыкания не менялся. Тогда бы - как только замкнули (myScope = C), - проанализировали кусок кода, где замкнули, поняли для себя , какие там должны быть значения слотов [[Scope]]Замыкания и вуа-ля - спокойно используем, надежно зная и понимая , какие значения будут у переменных [[Scope]]Замыкания при вызове замкнутой функции через Замыкание ( myScope(2) ) - НЕТ никаких проблем !

НО ! Вот после того, как замкнули, этот пресловутый [[Scope]] Замыкания может еще меняться программой ДО того, как стали вызывать Замкнутую функцию через Замыкание и проанализировать это довольно не просто. И поэтому я и привел пример (причем ,довольно интересный, с частичным выходом из Контекста Замыкания), иллюстрирующий наиболее ясно эту проблему и попытался максималоьно кратко дать объяснение - Когда Программа может менять слоты [[Scope]]'a' Замыкания .
Поэтому непонятно ТОЛЬКО одно (нет , ну, конечно, непонятным при обнаружении новых фактов может стать все , что угодно ), но пока это :
- КАК максимально кратко и ясно описать основную проблему при работе с Замыканиями - Когда Программа может менять слоты [[Scope]]'a' Замыкания ? Я попытался так , как попытался, Вы считаете, что плохо, или не хотите "расшифровывать примеры", не знаю ...

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

Сообщение от kefi
Вы считаете, что плохо, или не хотите "расшифровывать примеры", не знаю ...
Я не считаю, что плохо, только примеры повторяются, сначала было про 'c', теперь 'a,b,c', идея та же, какие там проблемы-то? Всё работает, как должно работать, функция "помнит" объекты в scope chain, а не значения (их вообще в момент создания может не быть), если значения позднее меняются, то они меняются...

function A() {
    // в момент создания [[Scope]] функции 'В'
    // переменной 'x' вообще не существует
    function B() {
        alert(typeof x);
    }
    // в момент вызова тоже
    B();
    eval('var x = 1');
    // теперь есть
    B();
}

A();

Последний раз редактировалось Zeroglif, 17.04.2009 в 23:59.
Ответить с цитированием
Ответ



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

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