Как именно связывание выполняется в замыканиях?
function f() { return s; } // works fine though no `s` is defined yet !
var s=1;
f(); // 1
delete s;
var s=2;
f(); // 2
(function() {
var s=3;
f(); // 2 and not 3 which means lexical scoping is at play (?)
})();
во-первых, вы можете закрыть переменную (s
) который еще не определен. Как это возможно, если используется лексическая (статическая) область видимости?
во-вторых, после удаления оригинала s
, f()
могу найти новый s
, Означает ли это, что замыкания связаны с именами переменных, а не с ссылками или индексами таблиц символов или чем-то более машинного уровня? Я ожидаю от закрытия лексической области видимости, чтобы выдать ошибку, так как оригинал s
удален Новый s
просто повторно использует имя и не имеет ничего общего с оригиналом s
,
И в-третьих, s
внутри области анонимной функции не используется f()
Означает ли это, что лексическая область видимости играет важную роль?
2 ответа
Этот пример эквивалентен
var s;
function f() { return s; } // works fine though no `s` is defined yet !
s=1;
f(); // 1
delete s;
s=2;
f(); // 2
(function() {
var s=3;
f(); // 2 and not 3 which means lexical scoping is at play (?)
})();
Объявления переменных Javascript поднимаются до верха их области видимости и затем объявляются. Затем они определяются, где пользователь устанавливает их. Таким образом, вы можете ссылаться на переменную javascript до ее объявления в области видимости функции.
Также обратите внимание, что delete обычно используется для свойств объекта, а не объекта, объявленного с помощью var. Удалить в этом случае не имеет никакого эффекта, независимо от закрытия. Смотрите скрипку здесь: jsfiddle
во-первых, вы можете закрыть переменную (переменные), которая еще не определена... как это возможно, если используется лексическая (статическая) область видимости?
См. Подъем
во-вторых, после удаления исходного s, f() может найти новый s. Означает ли это, что замыкания связаны с именами переменных, а не с ссылками или индексами таблиц символов или чем-то более машинного уровня? Я ожидаю, что от закрытия лексической области видимости выдается ошибка, поскольку исходный s - delete. Новые s просто повторно используют имя и не имеют ничего общего с оригинальными s.
Новых s нет, все объявления подняты. В конце есть только один с. Подъем по-прежнему применяется.
и, в-третьих, функция f внутри анонимной функции не используется функцией f (). Означает ли это, что лексическая область видимости действует?
Да, s внутри анонимной функции является локальным для нее, и в этом случае замыкание формируется над глобальным s.