Цитата:
Цитата:
Цитата:
|
2 Zeroglif >
мда, что-то мутно там. Мог бы кто понятно объяснить эти [[scope]], VO, контекст и иже с ними (какие-то, оказывается, еще спец объекты бывают ... ) , какие из этих объектов когда создаются, что они содержат и какие из них свойствами каких являются : - при доRUN-time'оых FD определениях функций , - при FE определениях функций , - при вызове функций ? |
Вообще, там достаточно информации было, но попробую ещё проще; по частям, чтобы "уварилось". Начнём с VO.
Variable object (Объект переменных, сокращённо VO) - это объект, служащий хранилищем для: 1. переменных (var); 2. деклараций функций (function declaration, FD); 3. формальных параметров функции; Главной особенностью здесь является то, что VO наполняется при входе в контекст, т.е. до выполнения кода контекста. Причём, в случае var'ов и недостающих формальных параметров под "наполнением" подразумевается резервирование слотов в VO со значением undefined. Пример: function test(a, b) { var c = 10; function d() {} var e = function _e() {}; (function x() {}); } test(10); // вызов Этапы вызова: 1. Вход в контекст: VO = { // упрощённо; в реале он "наследуется" от Объекта активации a: 10, b: undefined, c: undefined, d: <reference to functionBody> e: undefined }; 2. Исполнение контекста: VO['c'] = 10; VO['e'] = <reference to "_e" functionBody>; Всё. Как видим, функция "x", являясь FE (function expression), а не FD, не попала в VO (поскольку, ничего не было сказано про воздействие FE на VO в пунктах выше). Если попробовать вызвать функцию "x" за пределами объявления - будет ReferenceError. С другой стороны, "_e" также является FE, но последующее присвоение её переменной "e" оставляет на неё ссылку через VO["e"]. Если здесь всё понятно, и есть желание дальше изучать, можно будет продолжить. update: Эм.. Оказывается, я уже в этой теме писал почти тоже самое. |
Цитата:
а еще есть arguments, [[scope]] , etc ... Да, и еще бы понять, чьи они свойства - если функции , то в глобальном контексте если находимся - тогда чьи ? |
Цитата:
Кстати, в предыдущем посте, говоря о VO, в большей мере имелся в виду VO функции. AO создаётся при входе в контекст функции и инициализируется свойством arguments, значением которого является Arguments object (Объект аргументов, обозначим ArgO, чтобы не путать с AO): AO = { arguments: <ArgO> }; Далее, этот AO становится ничем иным как VO. Поэтому, говоря о VO в контексте типа "функция", можно использовать и терминологию AO, т.к. здесь VO === AO. Образно в предыдущем посте (чтобы не перегужать и не приплетать arguments) я назвал это "наследуется", физически же, это тот же самый объект. Говоря о VO в глобальном контексте, - сам глобальный объект является VO (в браузере - window). Цитата:
- callee - ссылка на выполняемую функцию; - length - количество реально переданных параметров; - свойства-индексы (числовые, приведённые к строке), значения которых есть формальные параметры функции (слева направо в списке параметров). Количество этих свойств-индексов == arguments.length. Значения свойств-индексов объекта arguments и присутствующие формальные параметры - взаимозаменяемы: function a(x, y, z) { alert(arguments.length); // 2 alert(arguments.callee === a); // true alert(x === arguments[0]); // true alert(x); // 10 arguments[0] = 20; alert(x); // 20 x = 30; alert(arguments[0]); // 30 } a(10, 20); Цитата:
Если всё понятно, можно будет продолжить про [[Scope]]. |
Я понял так , еще немного допридумал, чтобы было логичнее, проверьте что не так :
Variable object (Объект переменных, сокращённо VO) - это объект, служащий хранилищем для: 1. переменных (var); 2. деклараций функций (function declaration, FD); 3. формальных параметров функции; Главной особенностью здесь является то, что VO наполняется при входе в контекст, т.е. до выполнения кода контекста. Причём, в случае var'ов и недостающих формальных параметров под "наполнением" подразумевается резервирование слотов в VO со значением undefined. Для глобального контекста : VO===Global (где Global - встроенный глобальный объект) нашпиговывается ДО run-time слотами, которые по мере работы программы могут менять свои значения, но не свое количество или имена ! Для функции : Если не было входа управления в контекст функции, то не существует для нее никакого ни VO, ни AO. Если управление вошло во внутренний контекст функции F , то ДО ее выполнения для этой функции создается свой VO', при этом выполняются след шаги : arguments = [<0аргумент>,<1аргумент,...]; arguments.callee=F; arguments.length=<КолвоАргументовФункции_F>; AO = { arguments: arguments }; F.VO=AO; При выходе из контекста функции выполняется : delete F.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 в цепи, стоящие иерархически выше - остаются в памяти. |
2 Dmitry A. Soshnikov >
Все яснее и яснее, Я сам-то мучился с этими терминами, понимал для себя только , что есть внешний контекст для каждой функции и внутренний. И как это все Вы поняли из ECMA спецификации , ума не приложу ... Кстати контекст, как я сейчас понимаю, не является термином обозначающим некий объект, это чисто лексический контекст для текста функции или какого-ни слова из кода программы ? Вот правда, еще остается непонятной роль AO - вроде как и нни к чему он , да еще какой-то непонятныйц остается спец объект из Вашей ссылки выше. Цитата:
- именно на [[Scope]] , т.е. БЕЗ VO функции d ? - и сохраняются не просто , если возвращается return, как в Вашем примере b() , а если возвращаемое где-то сохранено var q=b() ? |
Цитата:
Цитата:
Цитата:
Цитата:
(function fn() {alert(fn);})(); Откуда alert(fn) выдаёт правильное значение, если FE не воздействуют на VO? Идентификатор fn не должен был попасть в VO(Global). Где же FE его находит? Специально для этого перед созданием FE создаётся этот спец. объект и кладётся в scope chain (в данном случае Global): Scope(Global).{}.fn = <reference to FE "fn"> Дальше, когда создалась FE "fn", этот спец. объект удаляется из Scope(Global) - теперь он есть в [[Scope]](fn) и, соотвественно, может быть найден. Здесь ещё можно почитать. Цитата:
Цитата:
|
Цитата:
|
Часовой пояс GMT +3, время: 13:18. |