Цитата:
Цитата:
Цитата:
|
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, время: 04:56. |