Переменная JavaScript undefined vs not defined
У меня есть HTML-страница со следующим приложением JavaScript.
alert(box);
box = "Thinking outside the box";
В консоли я получаю сообщение "Uncaught ReferenceError: box не определено"
когда я меняю его на:
alert(box);
var box = "Thinking outside the box";
Звонок вызывается и показывает undefined. Я должен уметь это объяснить, у меня есть смутное представление о том, почему это происходит. Я знаю, что, когда я использую var, JavaScript знает, что переменная существует до того, как будет выполнено предупреждение, но необязательно присвоить ей значение? Неужели я здесь? Нужна помощь в понимании этого.
Ответы
Ответ 1
Когда вы определяете переменную с var
, объявление переменной "поднимается" вверху области и, следовательно, переменная определяется для всей области. Инициализация переменной (присвоение ее начального значения) остается в том же месте в коде.
Итак, во втором примере, когда вы делаете alert(box)
, переменная box
уже объявлена из-за инструкции hoisted var
. Второй пример:
alert(box);
var box = "Thinking outside the box";
в основном эквивалентен этому (объявление переменной box
поднимается вверху области):
var box;
alert(box);
box = "Thinking outside the box";
Это делает переменную box
объявленной (хотя и не инициализированной) перед вашим оператором alert(box)
и, следовательно, вы получаете результат, который согласуется с объявляемой переменной, но еще не имеет значения (отчеты alert()
undefined
что происходит, когда переменная существует, но еще не инициализирована).
В вашем первом примере не используется var
, и, таким образом, нет никакого подъема, так что в точке, где вы выполняете alert(box)
, вообще нет переменной с именем box
, и вы получаете uncaught reference error
.
На SO есть много, много сообщений, которые описывают детали подъема. Вы можете увидеть длинный список из них здесь: https://stackoverflow.com/search?q=javascript+variable+hoisting, где вы найдете дополнительные пояснения о подъеме переменных.
Примечание: объявления функций также поднимаются, поэтому некоторые из сообщений, которые вы найдете, будут описывать объявления функций, а не объявления переменных, хотя концепция почти такая же.
Ответ 2
Это связано с переменным подъемом. Это означает, что объявления переменных (и декларации вообще) обрабатываются до того, как выполняется какой-либо код, объявление переменной в любом месте кода эквивалентно объявлению ее вверху. Это также означает, что переменная может отображаться для использования до ее объявления.
Когда вы выполните следующее:
alert(box)
var box = "Thinking outside the box"
Это неявно понимается как:
var box;
alert(box);
box = "Thinking outside the box"
В вашем первом случае у вас нет объявлений переменных, и, следовательно, они не подняты, в этом поле точки undefined
Почему это происходит?
Как Стоян Стефанов объясняет в своей книге "Шаблоны JavaScript", подъем является результатом реализации интерпретатора JavaScript:
Для полноты, давайте упомянем, что на самом деле при реализации уровень вещей немного сложнее. Существует два этапа обработки кода, где переменные, объявления функций и формальные параметры создаются на первом этапе, который является этапом синтаксический анализ и вход в контекст. На втором этапе этап выполнение исполняемого кода, выражения функций и неквалифицированные идентификаторы (необъявленные переменные). Но для практических целей, мы можем принять концепцию подъема, которая на самом деле не определяемый стандартом ECMAScript, но обычно используется для описания поведение.
- Стоян Стефанов, "Шаблоны JavaScript"
Как прочитала сторона, связав эту статью от Safe Shepherd.