Сообщение от kefi
|
Для глобального контекста :
VO===Global (где Global - встроенный глобальный объект) нашпиговывается ДО run-time слотами, которые по мере работы программы могут менять свои значения, но не свое количество или имена !
|
До исполнения, если встречаются:
var и FD. Всё остальное (например, a = 10 (без var), либо явно - window.a = 10) - создаётся в runtime'e (и слот и его значение). Поэтому, Global свободно может менять свои слоты и значения этих слотов в runtime'e.
Сообщение от kefi
|
Если не было входа управления в контекст функции, то не существует для нее никакого ни VO, ни AO.
|
Да, так. Однако, [[Scope]] в функции зашит изначально и навсегда, не важно, будет ли запущена функция или нет.
Сообщение от kefi
|
Если управление вошло во внутренний контекст функции F , то ДО ее выполнения для этой функции создается свой VO', при этом выполняются след шаги :
|
Да.
Сообщение от kefi
|
F.VO=AO;
|
Можно и так, для удобства (абстрактно) обозначить.
Сообщение от kefi
|
delete F.VO
|
Да, только, если не было замыкания, тогда F.VO сохранится в [[Scope]] внутренней функции (т.е. не будет удалён, пока на него есть ссылка).
Сообщение от kefi
|
"Огласите весь список, пожалуйста."
|
[[Scope]] - это иерархическая цепь Объектов переменных (VO), стоящих выше контекста функции; цепь записывается свойством в функцию при её
создании.
Scope (Scope chain, Иерархия областей видимости (в данном переводе)) - это цепь Объектов переменных, в которой происходит поиск значений при разрешении имен идентификаторов. Данная цепь создаётся при
выполнении функии, и состоит из VO(текущей функции) и [[Scope]] функции:
Scope = VO + [[Scope]].
Можно ещё раз
здесь почитать.
Пример:
var a = 10;
function b() {
var c = 20;
function d() {
var e = 30;
alert(a + c + e);
}
d();
return d;
}
b();
Имеем:
VO(Global):
VO(Global) === Global = {
a: 10
b: <reference to functionBody>
};
При создании "b", [[Scope]] "b":
[[Scope]](b) = [
VO(Global)
];
VO(b):
VO(b) = {
c: 20,
d: <reference to functionBody>
};
При запуске "b", Scope(b) = VO(b) + [[Scope]](b):
Scope(b) = [
VO(b),
VO(Global)
];
При создании внутрененней функции "d", [[Scope]] "d":
[[Scope]](d) = [
VO(b),
VO(Global)
];
VO(d):
VO(d) = {
e: 30
};
При запуске "d", Scope(d) = VO(d) + [[Scope]](d):
Scope(b) = [
VO(d),
VO(b),
VO(Global)
];
Разрешение имён идентификаторов "a", "c" и "e" при alert'e:
- "a"
-- VO(d) - не найдено;
-- VO(b) - не найдено;
-- VO(Global) - найдено - 10.
- "с"
-- VO(d) - не найдено;
-- VO(b) - найдено - 20.
- "е"
-- VO(d) - найдено - 30;
Т.е. Scope опрашивается по цепи вверх, если идентификатор не найден в родном VO.
При
return d; остаётся ссылка на [[Scope]](d), поэтому все VO в цепи, стоящие иерархически выше - остаются в памяти.