为什么控制台上的 JavaScript 变量声明会导致打印“未定义”?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/22844840/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-27 23:51:48  来源:igfitidea点击:

Why does JavaScript variable declaration at console results in "undefined" being printed?

javascript

提问by Ken Russell

I have already read the following SO posts:

我已经阅读了以下 SO 帖子:

Why does this JavaScript code print “undefined” on the console?

为什么这段 JavaScript 代码会在控制台上打印“undefined”?

Why does Chrome & FireFox console print undefined?

为什么 Chrome 和 FireFox 控制台打印 undefined?

Why does the JS console return an extra undefined?

为什么 JS 控制台返回一个额外的 undefined?

But none of it explains why the JavaScript console prints undefinedwhen I declare a variable as follows:

但这都没有解释为什么当我如下声明变量时JavaScript 控制台打印undefined

var a;

var a;

回答by raina77ow

It prints the result of this expression - which is undefined. And yes, var ais a valid expression on its own.

它打印此表达式的结果 - 即undefined. 是的,var a它本身就是一个有效的表达方式。

Actually, you should rather be amused by why consoleprints undefinedwhen you write var a = 3or something like this. It also prints undefinedif function anyFunctionName() {}statement is processed. In fact, all the varand functiondeclaration (!) statements seem to be ignored if there's another statement with some 'real' result:

实际上,您应该对为什么在写作时console打印或类似的东西感到好笑。它还打印if语句已处理。事实上,如果有另一个具有“真实”结果的语句,则所有and声明 (!) 语句似乎都被忽略了:undefinedvar a = 3undefinedfunction anyFunctionName() {}varfunction

>>> var a = 3;
undefined

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

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

Now, I suppose the real reason behind is behaviour of evalstatement, as described here:

现在,我想背后的真正原因是行为的eval语句,描述在这里

  • Let resultbe the result of evaluating the program prog.
  • If result.typeis normaland its completion value is a value V, then return the value V.
  • If result.typeis normaland its completion value is empty, then return the value undefined.
  • result成为评估程序的结果prog
  • 如果result.typenormal并且其完成值为 a value V,则返回value V
  • 如果result.typenormal并且其完成值为empty,则返回该值undefined

So now the question is, what does var a = 4statement return? Guess what: it's not 4.

那么现在的问题是,var a = 4语句返回什么?猜猜看:不是 4。

The production VariableStatement: var VariableDeclarationList;is evaluated as follows:

  • Evaluate VariableDeclarationList.
  • Return (normal, empty, empty).

生产VariableStatement: var VariableDeclarationList; 评估如下:

  • 评估 VariableDeclarationList。
  • 返回(正常,空,空)。

Now the most interesting part: what happened in the last example, why 4 is the result? That's explained in this section:

现在最有趣的部分是:在最后一个例子中发生了什么,为什么结果是 4?本节对此进行了解释:

The production Program: SourceElementsis evaluated as follows:

  • Let result be the result of evaluating SourceElements.

[...]

The production SourceElements: SourceElements*SourceElement* is evaluated as follows:

  • Let headResult be the result of evaluating SourceElements.
  • If headResult is an abrupt completion, return headResult.
  • Let tailResult be result of evaluating SourceElement.
  • If tailResult.value is empty, let V = headResult.value, otherwise let V = > tailResult.value.
  • Return (tailResult.type, V, tailResult.target)

生产程序SourceElements的评估如下:

  • 让 result 是评估 SourceElements 的结果。

[...]

生产SourceElements: SourceElements*SourceElement* 评估如下:

  • 让 headResult 成为评估 SourceElements 的结果。
  • 如果 headResult 是突然完成,则返回 headResult。
  • 让tailResult 是评估SourceElement 的结果。
  • 如果 tailResult.value 为空,则让 V = headResult.value,否则让 V = > tailResult.value。
  • 返回(tailResult.type,V,tailResult.target)

Both function f() {}and var a = 5statements' return values were (normal, empty, empty). So the script ended up with giving out the result of the first statement (starting from the script's end, so technically it's the last one) that's not (normal, empty, empty). That is the result of a = 4assignment statement - which is 4.

双方function f() {}var a = 5声明“返回值是(normal, empty, empty)。所以脚本最终给出了第一个语句的结果(从脚本的末尾开始,所以从技术上讲它是最后一个)不是(normal, empty, empty). 那是a = 4赋值语句的结果- 即4.



P.S. And now for some icing on the cake: consider the following:

PS 现在让我们锦上添花:考虑以下几点:

>>> function f() {}
undefined

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

The difference is quite subtle: the first input is treated as a Function Declarationstatement, which, according to this rule...

区别非常微妙:第一个输入被视为一个Function Declaration语句,根据此规则......

The production SourceElement: FunctionDeclarationis evaluated as follows:

  • Return (normal, empty, empty).

生产SourceElement: FunctionDeclaration的评估如下:

  • 返回(正常,空,空)。

... will eventually produce undefinedwhen eval-ed, as we already know.

... 最终会产生undefinedwhen eval-ed,正如我们已经知道的那样。

The second input, however, is treated as a Function Expression, which is evaluated to the function itself. That means it'll be passed through evaland eventually returned to the console (in its format).

然而,第二个输入被视为 a Function Expression,它被评估为函数本身。这意味着它将被传递eval并最终返回到控制台(以其格式)。

回答by csharpwinphonexaml

var a=1;
a

gives:

给出:

1

while

尽管

var a=1;

gives:

给出:

undefined

in the first case the console evaluates a so it prints the value of a

在第一种情况下,控制台评估 a,因此它打印 a 的值

in the second case the console does not evaluate the value of a, but it evaluates the expression itself.

在第二种情况下,控制台不计算 a 的值,而是计算表达式本身。

回答by Graham Ritchie

because all you are doing is declaring there is a variable - what is it? a string, an integer, a boolean - we don't know yet - hence undefined

因为你所做的只是声明有一个变量——它是什么?一个字符串、一个整数、一个布尔值——我们还不知道——因此undefined