为什么控制台上的 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
Why does JavaScript variable declaration at console results in "undefined" being printed?
提问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?
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 programprog.- If
result.typeisnormaland its completion value is avalue V, then return thevalue V.- If
result.typeisnormaland its completion value isempty, then return the valueundefined.
- 让
result成为评估程序的结果prog。- 如果
result.type是normal并且其完成值为 avalue V,则返回value V。- 如果
result.type是normal并且其完成值为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

