为什么Javascript中的以下计算会给出这些结果?
{} + []
0
[] + {}
"[object Object]"
{} + {}
NaN
[] + []
""
发生了什么事?
答案 0 :(得分:4)
虽然看起来所有示例都使用了加法运算符,但实际上有一半使用了加法运算符(二进制 +
),而另一半使用了一元运算符+
运营商。
这些是使用加法运算符:
[] + {}
[] + []
这些是使用一元+
运算符:
{} + []
{} + {}
让我们从前两个开始:
[] + {}
[] + []
JavaScript addition operator是根据字符串(连接)和数字(加法)定义的,因此当它的操作数不是字符串或数字时,它会强制它们为。
规范中的完整细节,但基本上:首先两个参数都通过abstract ToPrimitive operation转换为基元,这可能导致几种基本类型(字符串,数字,布尔值)中的任何一种。然后,如果任一操作数是一个字符串,则另一个操作数被强制为字符串并完成连接。如果不是,则两者都被强制转换为数字并进行添加。
因此,如果您使用Number({})
和String({})
以及Number([])
和String([])
进行游戏,那么您将会看到正在发生的事情。
现在,让我们看看另外两个:
{} + []
{} + {}
这些非常棘手因为它们看似添加,但它们不是:它们是一个空的块,后跟一个使用{的表达式{3}}。当期望 语句或表达式时,如果解析器看到{}
,它会将其作为块语句处理。由于这些街区是空的,他们根本不做任何事情,我们留下了:
+ []
+ {}
最终将数组或对象强制转换为数字。 Number([])
为0
,Number({})
为NaN
。
如果我们强制解析器只期望一个表达式(可能使用()
),而不是表达式或语句,我们会看到不同的结果,因为我们回来了加法运算符:
({} + [])
"[object Object]"
{} + {}
"[object Object][object Object]"