Все правильно сказано, но вот что-то не достает для практического руководства, т.е. нужны какие-то
краткие , чтобы легко запомнить и одновременно предельно ясные, чтобы не ошибиться слова ,
поясняющие явление Замыкания.
У меня вот тоже не очень получается сложить такие слова.
попытался вот так, исправьте,плз, что не так :
/* Когда Программа может менять слоты [[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 - Полный выход из Контекста Замыкания
};