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

Сообщение от 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 в цепи, стоящие иерархически выше - остаются в памяти.
__________________
Тонкости ECMAScript

Последний раз редактировалось Dmitry A. Soshnikov, 15.04.2009 в 14:11.
Ответить с цитированием