Почему объявление переменной JavaScript на консоли приводит к печати "undefined"?

Я уже прочитал следующие сообщения SO:

Почему этот код JavaScript печатает "undefined" на консоли?

Почему консоль Chrome и FireFox печатает undefined?

Почему консоль JS возвращает дополнительный undefined?

Но ничто из этого не объясняет, почему консоль JavaScript печатает undefined, когда я объявляю переменную следующим образом:

var a;

Ответы

Ответ 1

Он печатает результат этого выражения - undefined. И да, var a является правильным выражением.

На самом деле вам следует позабавиться, почему console печатает undefined при написании var a = 3 или что-то вроде этого. Он также печатает undefined, если выполняется инструкция function anyFunctionName() {}. На самом деле все инструкции var и function declare (!) Кажутся проигнорированными, если есть другой оператор с некоторым "реальным" результатом:

>>> var a = 3;
undefined

>>> var a = 3; a = 4;
4

>>> var a = 3; a = 4; var a = 5; function f() {};
4 // !!!

Теперь я полагаю, что реальной причиной является поведение оператора eval, как описано здесь:

  • Пусть result будет результатом оценки программы prog.
  • Если result.type - normal, а его значение завершения - value V, верните value V.
  • Если result.type - normal, а его значение завершения empty, верните значение undefined.

Итак, теперь вопрос в том, что возвращает оператор var a = 4? Угадайте, что: это не 4.

Производство VariableStatement: var VariableDeclarationList; является оценивается следующим образом:

  • Оценить VariableDeclarationList.
  • Возврат (обычный, пустой, пустой).

Теперь самая интересная часть: что произошло в последнем примере, почему 4 - результат? Это объясняется в этом разделе:

Производственная Программа: SourceElements оценивается следующим образом:

  • Пусть результат будет результатом оценки SourceElements.

[...]

Источник SourceElements: SourceElements * SourceElement * оценивается следующим образом:

  • Пусть headResult будет результатом оценки SourceElements.
  • Если headResult является неожиданным завершением, верните headResult.
  • Пусть tailResult является результатом оценки SourceElement.
  • Если tailResult.value пуст, пусть V = headResult.value, в противном случае пусть V = > tailResult.value.
  • Возврат (tailResult.type, V, tailResult.target)

Оба возвращаемых значения function f() {} и var a = 5 были (normal, empty, empty). Таким образом, script закончил выдачу результата первого оператора (начиная с конца script, так что технически это последний), а не (normal, empty, empty). Это результат оператора присваивания a = 4 - 4.


P.S. И теперь для некоторой глазури на торте: рассмотрите следующее:

>>> function f() {}
undefined

>>> (function f() {})
function f() {}

Разница довольно тонкая: первый вход рассматривается как оператор Function Declaration, который, согласно этому правилу...

Производство SourceElement: FunctionDeclaration оценивается как следующим образом:

  • Возврат (обычный, пустой, пустой).

... в конечном итоге произведет undefined, когда eval -ed, как мы уже знаем.

Второй вход, однако, рассматривается как Function Expression, который оценивается самой функции. Это означает, что он будет передан через eval и в конечном итоге вернется на консоль (в его формате).

Ответ 2

потому что все, что вы делаете, объявляет, что есть переменная - что это такое? строка, целое число, логическое значение - мы еще не знаем - следовательно undefined

Ответ 3

var a=1;
a

дает:

1

а

var a=1;

дает:

undefined

в первом случае консоль оценивает значение a, чтобы оно печатало значение

во втором случае консоль не оценивает значение a, но оценивает само выражение.