Локальная проблема области видимости Javascript
если я сделаю это:
var a = 0;
(function () {
var a = a; //want to make local a = global a
++a;
console.log("fn",a);
})();
console.log(a);
выход:
fn NaN
0
почему a
внутри самоисполняющейся функции стать NaN
?
Я знаю, что это работает нормально, если я делаю:
(function () {
var b = a;
++b;
console.log("fn",b); // fn 1
})();
но если я пойду по пути первой версии, у нее есть NaN
вопрос.
почему это происходит?
4 ответов
var a = a;
на самом деле var a; a = a;
из-за переменной поднимая. Это означает, что на момент назначения старый a
уже затенен новым (который является undefined
).
самый простой способ избежать подобных проблем-передать значение в качестве параметра:
(function (a) {
++a;
console.log("fn",a);
})(a);
в случае a
является глобальной переменной, которую вы также можете использовать var a = window.a;
как Возняк предложил - но поскольку глобальные переменные обычно являются плохой идеей, лучше оставаться с параметры.
на a
переменной внутри выражения функции тени the a
переменная, объявленная во внешней области.
становится NaN
, так как в задании:
var a = a;
правой a
это на самом деле имею в виду a
в локальной области.
объявления переменных выполняются до того, как функция фактически начнет выполняться, это обычно известно как "подъем".
так как это то же самое переменная, она содержит undefined
значение, и когда вы пытаетесь добавить любое число к этому значению, оно становится NaN
:
console.log(undefined + 0);
в JavaScript текущий контекст исполнения (который включает в себя такие вещи, как переменная область) устанавливается до начинается выполнение кода.
для вас это означает, что сначала выделяются имена локальных переменных. Из-за поднимать, метки var
заявления в любом месте функции инициализируются undefined в текущем контексте исполнения. (инструкции функции также инициализируются на этом шаге.)
далее, ваш код фактически начинает выполняться. The a
метка уже зарезервирована в текущем контексте выполнения, поэтому var a = a;
просто назначает local a
(т. е. undefined) к себе.
var a = window.a
работает, потому что вы обходите проблему области, напрямую обращаясь к глобальной области. Однако это не работает в средах без браузера (например, Node), потому что нет window
; глобальный объект в узле global
.
в javascript есть переменная, поэтому ваш код во время выполнения выглядит так:
(function () {
var a;
a = a; //want to make local a = global a
++a;
console.log("fn",a);
})();
Итак, сначала у вас есть локальная переменная a как неопределенная, а затем вы назначаете неопределенную переменной a