为什么控制台上的 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 a
is a valid expression on its own.
它打印此表达式的结果 - 即undefined
. 是的,var a
它本身就是一个有效的表达方式。
Actually, you should rather be amused by why console
prints undefined
when you write var a = 3
or something like this. It also prints undefined
if function anyFunctionName() {}
statement is processed. In fact, all the var
and function
declaration (!) statements seem to be ignored if there's another statement with some 'real' result:
实际上,您应该对为什么在写作时console
打印或类似的东西感到好笑。它还打印if语句已处理。事实上,如果有另一个具有“真实”结果的语句,则所有and声明 (!) 语句似乎都被忽略了:undefined
var a = 3
undefined
function anyFunctionName() {}
var
function
>>> 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 eval
statement, as described here:
现在,我想背后的真正原因是行为的eval
语句,描述在这里:
- Let
result
be the result of evaluating the programprog
.- If
result.type
isnormal
and its completion value is avalue V
, then return thevalue V
.- If
result.type
isnormal
and 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 = 4
statement 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 = 5
statements' 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 = 4
assignment 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 Declaration
statement, which, according to this rule...
区别非常微妙:第一个输入被视为一个Function Declaration
语句,根据此规则......
The production SourceElement: FunctionDeclarationis evaluated as follows:
- Return (normal, empty, empty).
生产SourceElement: FunctionDeclaration的评估如下:
- 返回(正常,空,空)。
... will eventually produce undefined
when eval
-ed, as we already know.
... 最终会产生undefined
when 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 eval
and 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