Я не уверен, я понимаю ваш вопрос, но это, как я понимаю, сек 10.4.3:
шаги с 1 по 4 имеют дело со значением этого. В основном, в строгом режиме, будет оставлен до значения null
или undefined
, а не по умолчанию для глобального объекта (window
в случае браузера). Это охватывает случаи, когда функция не вызывается через обычные механизмы обработчика объекта или события.
шаг 5 до 7 означает, что новая среда именование создается каждый раз при входе в функцию. В нем описывается создание этой среды, которая связана с предыдущей, чтобы сформировать текущую область имен.
Для каждой новой функции две среды сосуществуют. Когда имя разрешено, сначала выполняется поиск по лексической среде, а затем переменная среда. Если оба запроса не выполняются, процесс повторяется на верхнем уровне цепочки окружения, пока не будет обнаружена глобальная область «catch-all». В этой области все идентификаторы обрабатываются как свойства глобального объекта (window
). Вы можете представить его как полный код, заключенный в блок with (window)
.
Лексическую среду можно рассматривать как временное увеличение области переменных. Лексические и переменные среды: functionnally идентичны до тех пор, пока вы не измените лексическую среду с помощью двух конкретных операторов: with
или catch
. Это не значит, что они реализованы как идентичные структуры данных.
С точки зрения реализации вы можете представить себе лексическую среду как пустой список и переменную среду как список, содержащий все локальные переменные и имена параметров. Когда встречается оператор catch
или with
, лексический список заполняется новыми именами, которые будут иметь приоритет над хранимыми в списке переменных.
catch
просто сделает свой аргумент доступным для разрешения имен (т. Е. Позволит вам ссылаться на параметр исключения). Не имеет большого значения, поскольку новое имя так же явно, как и параметр функции.
with
- более опасное зверь. Он создаст новую среду с именами всех свойств объекта, переданного в качестве аргумента. Объем будет состоять из цепочки переменная среды плюс этот новый лексический окружающая среда. Здесь новые имена, доступные для разрешения, «скрыты» внутри объекта. Например:
var a = 'a', b = 'surprise!', o = {a:'a'};
with (o) { a = b; }
console.log (a+" "+b+" "+o.a);
даст
a surprise! surprise!
a
решается, как o.a
, поскольку o
содержит свойство с именем a
. b
не найден внутри лексических окружающей среды и, таким образом, текущий переменная окружающая среда суждена и переменная 'b'
не найден. Это довольно опасный механизм, потому что, если вы считаете, что объект содержит заданное свойство, а на самом деле его нет, вы вместо этого ссылаетесь на переменную за пределами текущей области. Например, простая опечатка, как это:
with (element.style) {leftt = '10px';}
установит window.leftt
свойство '10px'
, если не случится объявили переменную с именем leftt
где-то в текущей области.
Теперь, если вы дадите глупые имена, такие как «i» или «j», к вашим свойствам объекта, скорее всего, вы будете клонировать индекс случайного цикла где-нибудь в цепочке областей, полагая, что вы устанавливаете свойство объекта.
Этап 8 описывает связывание параметров после установления диапазона функций. В принципе, параметры связаны со значениями и их имена добавляются в переменную среду.
Весь смысл держать две отдельные среды является то, что Подъемный механизм всегда использует переменную среды цепь в качестве рамки.
Идея состоит в том, что переменная или функция должны вести себя так, как если бы она была указана в верхней части текущего блока области видимости, поэтому, например, функция, объявленная внутри блока с блоком, не должна разрешать свои имена с помощью свойств объекта, с заявлением.
Откровенно говоря, это довольно спорный вопрос, поскольку спецификация ECMA не позволяет объявлять функции внутри блоков, хотя большинство реализаций делают, с результатами varrying.
Теперь для примера:
function foo(){
var a={p:'p'};
o={c:'c'};
}
Ваша функция не содержит никаких with
или catch
заявления, поэтому цепочка областей внутри «Foo()» это просто список из двух переменных среды:
global (a bunch of DOM objects all seen as properties of 'window')
function foo (var a)
после вызова Foo(),
a
будет разрешен как локальная переменная foo, будет создан как объект с свойством p
значения 'p'
(и сбор мусора, как только вы покинете foo(), если только вам не удастся ссылаться на него из постоянной переменной).
o
не будет найден в переменной окружения Foo, так что он будет пойман «поймать-все» глобального масштаба и, таким образом, решить, как (новое) свойство window
объекта. Он создаст объект window.o.c
со значением 'c'
.
Отвечает ли это на ваш вопрос?
Я не уверен, понял ли я этот вопрос. «LexicalEnvironment» и «VariableEnvironment» получают одинаковое значение, назначенное в 6 и 7. –
@Felix Kling На шаге 8 переменные контекста и функции, объявленные в коде, будут добавлены как привязки в записи среды VariableEnvironment. Но как насчет LexicalEnvironment? Будут ли эти привязки добавлены в LexicalEnvironment на шаге 8? А что такое '[[Scope]]' внутреннее свойство функции в моем конкретном случае? –
Это хороший вопрос. Я бы предположил, что это похоже на объекты: LexicalEnvironment и VariableEnvironment относятся к одной и той же среде, и, следовательно, любые изменения, внесенные в эту среду, видны через оба компонента. В вашем примере '[[Scope]]' будет ссылаться на лексическую среду глобального контекста выполнения, поскольку вы определили функцию в глобальной области. См. Http://www.ecma-international.org/ecma-262/5.1/#sec-13 –