Локальная проблема области видимости 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