Ответ 1
Это явление известно как: Перемещение JavaScript Variable.
Ни в коем случае вы не обращаетесь к глобальной переменной в своей функции; вы всегда получаете доступ к локальной переменной 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); }
который даст вам опорную ошибку:
Неподготовлено ReferenceError: тест не определен
Это отбрасывает множество разработчиков, так как этот фрагмент кода работает отлично:
test("Works!");
function test(text) { alert(text); }
Причиной этого, как указано, является то, что часть назначения не поднята. Итак, в первом примере, когда был запущен test("Won't work!")
, переменная test
уже объявлена, но еще не назначена ей функция.
Во втором примере мы не используем назначение переменной. Скорее, мы используем правильный синтаксис объявления функции, который полностью выполняет функцию.
Ben Cherry написал прекрасную статью об этом, соответственно названную JavaScript Обзор и подхват.
Прочтите. Это даст вам полную картину в полной мере.