Закрытие JavaScript против.Местный
-
21-12-2019 - |
Вопрос
У меня есть основной файл Javascript, который заключен в немедленно вызываемое замыкание (чтобы не загрязнять «глобальный»:
(function () {
"use strict";
var closureVariable = [];
...
}());
Я допустил простую, грубую ошибку кода при удалении переменной из заголовка функции, так что в моем коде вместо точки с запятой стояла запятая:
function fred () {
var i,
closureVariable = [1,2,3,4];
confused();
}
function confused () {
console.log(closureVariable); // Prints '[]'
}
Конечно, проблема заключалась в отсутствующей точке с запятой в строке «var i».Однако поведение, которое, как я думал, должно произойти, заключается в том, что моя теперь локально определенная переменная 'closureVariable' должна была затенить определение области более высокого уровня, а значение моей локально определенной переменной должно было быть доступно функциям ниже в цепочке области видимости ( то есть функция «confused» должна была вывести «[1,2,3,4]»;
Что я здесь не понимаю в цепочках областей видимости Javascript?
Решение
То, что вы ожидаете, известно как динамическая область видимости.Это правильный выбор языкового дизайна, хотя сегодня многие считают его худшим.Это просто не то, что делает Javascript.Как и многие популярные языки, Javascript использует лексическая область видимости.Это значит confused
область видимости не считается дочерней областью fred
s, потому что его определение не находится внутри определения fred
.Дело в том, что fred
звонки confused
не имеет никакого эффекта.
Другие советы
var i,
closureVariable = [1,2,3,4];
создает две новые переменные, доступные в fred
функция и функции, определенные в этой области.
Эти переменные полностью отличаются от любой переменной, определенной вне fred
область видимости, даже если они имеют одно и то же имя.
Затенение здесь означает, что ваша переменная с именем "closureVariable"
предотвращает любой прямой доступ к переменной с тем же именем во внешней области.
Когда вы переопределили закрывающуюся, опускав точку с запятой, он был переопределен только в контексте функции Фреда.Смущенная функция существует в контексте вашего замыкания, поэтому он все еще видит оригинал ClackureVariable.Если бы у вас была путаница функции, определенная внутри функции FRED, она бы увидела новую ClosureVariable и будет печатать [1,2,3,4]
(function () {
"use strict";
var closureVariable = [];
function fred () {
var i,
closureVariable = [1,2,3,4];
function confused () {
console.log(closureVariable);
}
confused(); // print [1,2,3,4]
}
})();
.
Или, если вы хотите позвонить смущенным из-за пределов FRED ()
(function () {
"use strict";
var closureVariable = [];
var confused;
function fred () {
var i,
closureVariable = [1,2,3,4];
confused = function () {
console.log(closureVariable);
}
}
confused(); // print [1,2,3,4]
})();
.