Показать сообщение отдельно
  #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.
Ответить с цитированием