Удивлен, что глобальная переменная имеет неопределенное значение в JavaScript


сегодня я был совершенно удивлен, когда увидел, что глобальная переменная имеет undefined значение в определенном случае.

пример:

var value = 10;
function test() {
    //A
    console.log(value);
    var value = 20;

    //B
    console.log(value);
}
test();

дает выход как

undefined
20

здесь, почему движок JavaScript рассматривает глобальное значение как undefined. Я знаю, что JavaScript-это интерпретируемый язык. Как он может рассматривать переменные в функции?

это ловушка от движка JavaScript?

4 75

4 ответа:

это явление известно как:JavaScript Переменная Подъем.

ни в коем случае вы не получаете доступ к глобальной переменной в своей функции; вы только когда-либо получаете доступ к локальному value переменной.

ваш код эквивалентен следующему:

var value = 10;

function test() {
    var value;
    console.log(value);

    value = 20;
    console.log(value);
}

test();

все еще удивлен, что ты получаешь undefined?


объяснение:

это то, что каждый программист JavaScript натыкается рано или поздно позже. Проще говоря, любые переменные, которые вы объявляете, всегда подняли в верхней части вашего местного закрытия. Итак, даже если вы объявили свою переменную после первого console.log вызов, это все еще считается, как если бы вы объявили об этом раньше.
Однако поднимается только часть декларации; назначение, с другой стороны, нет.

Итак, когда вы впервые позвонили console.log(value), вы ссылались на локально объявленную переменную, которая ничего не получила назначено ему еще; отсюда undefined.

здесь еще один пример:

var test = 'start';

function end() {
    test = 'end';
    var test = 'local';
}

end();
alert(test);

как вы думаете, что это будет предупреждать? Нет, не просто читайте дальше, подумайте об этом. Что такое значение test?

если бы ты сказал что-нибудь кроме start, вы ошибались. Приведенный выше код эквивалентен этому:

var test = 'start';

function end() {
    var test;
    test = 'end';
    test = 'local';
}

end();
alert(test);

так что глобальная переменная не влияет.

как вы можете видеть, независимо от того, где вы положили переменную объявление, Это всегда подняли в верхней части вашего местного закрытия.


Примечание:

это также относится к функциям.

считают этот кусок кода:

test("Won't work!");

test = function(text) { alert(text); }

который даст вам ссылку на ошибку:

Uncaught ReferenceError: тест не определен

это сбивает с толку многих разработчиков, так как этот кусок кода отлично работает:

test("Works!");

function test(text) { alert(text); }

причина этого, как указано, заключается в том, что часть назначения не подсадили. Так что в первом примере, когда test("Won't work!") работает,test переменная уже объявлена, но ей еще не назначена функция.

во втором примере мы не используем переменную назначения. Скорее, мы используем правильный синтаксис объявления функции, который тут получить функцию полностью поднятый.


Бен Вишня написал отличную статью об этом, соответственно под названием JavaScript Scoping and Hoisting.
Прочитать его. Это даст вам всю картину в полном объеме.

Я был несколько разочарован, что проблема здесь объяснено, но никто не предложил решение. Если вы хотите получить доступ к глобальной переменной в области действия функции без функции, создающей сначала неопределенный локальный var, ссылайтесь на var как window.varName

переменные в JavaScript всегда имеют область действия в пределах функции. Даже если они были определены в середине функции, они заметны раньше. Подобные явления могут наблюдаться и при функциональном подъеме.

Это, как говорится, "первый"!--0--> видит value переменная (внутренняя, которая затеняет внешнюю value), но он еще не был инициализирован. Вы можете думать об этом так, как если бы все объявления переменных были неявно перемещены в начало функции (не внутренний блок кода), а определения остались на том же месте.

см. также

есть глобальная переменная value, но когда управление переходит к