为什么在Javascript中 {} + [] 返回0?

43
Possible Duplicate:
What is the explanation for these bizarre JavaScript behaviours mentioned in the 'Wat' talk for CodeMash 2012?

I know that when [] is coerced to a string it returns the empty string (""), and when {} is coerced to a string it returns "[object Object]".

When I run [] + {} in my browser's Javascript console, it returns "[object Object]", which is not what I expected.

>> [] + {}
"[object Object]"

但是当我运行{} + []时,它返回了一个完全意料之外的值:

>> {} + []
0

是什么导致它返回0


看起来你正在将 null 加上 null。这相当于 0 + 0。不过这只是猜测。 - Trisped
4
@Trisped: 两者都不是空的。 - SLaks
2
这个问题已经被 https://dev59.com/amox5IYBdhLWcg3wsGWC(目前有301票)所包含...... - Ray Toal
2
有人在看《Wat》这个视频吗?是不是因为想学习编程知识啊?:P - ardent
3个回答

68

当语句以{开头时,它将被解释为一个语句块,其中可以包含零个或多个语句。一个没有语句的语句块将具有空的连续值。

换句话说,在这种情况下,{}被解释为空代码块。

该语句在结束括号}后结束,这意味着接下来的三个字符+ []构成了一个新的语句。

在表达式或语句的开头,+是一元正号运算符,它将其操作数强制转换为数字。

因此+ []等同于Number([]),它的结果是0

总之,{} + []是一个空代码块,后跟一个被强制转换为数字的数组。


所有这些说法都是建立在你在表达式中计算{} + []的前提下,它将返回你所期望的结果:

>> ({} + []) 
"[object Object]" 

另一个有趣的事情是,你不能以对象字面量开始一个语句,因为解释器会尝试将其解析为语句。 这样做

{ "object": "literal" };

会抛出语法错误。


4
有趣的是,如果您在语句开头省略属性名称的引号,则单个属性的对象文字不会成为语法错误。它只是不像看起来那样有意义。例如,{ object: "literal" }被解释为一个带有单个语句 "literal" 的块语句。 object 成为语句的标签。 - Matthew Crumley
@MatthewCrumley 这是因为 object: 被视为标签(可以与 break 语句一起使用的那种)。 - Ruan Mendes
@Peter Olson。感谢您的回复。然而,表达式 { "object": "literal" }; 只会在 Firefox 中抛出错误。Chrome 将其视为对象字面量。 - Cels

20

因为{}被视为一个块,所以你的语句实际上是:

{

//empty block here
}

+[] //0 same as Number([])

这就是为什么这段代码是无效的 JavaScript:

eval('{hello: "world", key: "value"}') //Syntax error
您可以添加()使其成为表达式(块无法用于表达式,因此它将是对象初始化程序:)
eval('({hello: "world", key: "value"})') //Object

2
我对这个答案的问题并不明显,所以请解释一下为什么要点踩。 - Esailija
2
+1 抵消踩票。你比他早了大约25秒,我认为你的多行示例更清晰。 - Izkata

2
空块被强制转换为零。然后,+ 运算符决定将 [] 强制转换为数字。

1
空块就是一个空块,它不会被强制转换成任何东西。 - alex
1
@alex,您是正确的,在阅读了Peter Olsen的答案后,我明白唯一的强制转换是将数组转换为数字,并且第一组方括号只是被忽略掉了,最后一个语句被返回。 - Ruan Mendes

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接