我知道当[]
被强制转换为字符串时,它返回空字符串 ( ""
),而当{}
被强制转换为字符串时,它返回"[object Object]"
。
当我[] + {}
在浏览器的 Javascript 控制台中运行时,它会按预期返回:
>> [] + {}
"[object Object]"
但是当我运行时{} + []
,它返回一个完全出乎意料的值:
>> {} + []
0
什么可能导致它返回0
?
我知道当[]
被强制转换为字符串时,它返回空字符串 ( ""
),而当{}
被强制转换为字符串时,它返回"[object Object]"
。
当我[] + {}
在浏览器的 Javascript 控制台中运行时,它会按预期返回:
>> [] + {}
"[object Object]"
但是当我运行时{} + []
,它返回一个完全出乎意料的值:
>> {} + []
0
什么可能导致它返回0
?
当{
语句开头有 a 时,它将被解释为一个块,其中可能包含零个或多个语句。一个没有语句的块将有一个空的延续值。
换句话说,在这种情况下,{}
被解释为一个空代码块。
语句在结束大括号之后结束}
,这意味着接下来的三个字符+[]
组成了它们自己的语句。
在表达式或语句的开头+
是一元加号运算符,它将其操作数强制为一个数字。
So+[]
与 相同Number([])
,其计算结果为0
。
简而言之,{} + []
是一个空代码块,后面跟着一个强制为数字的数组。
综上所述,如果您{} + []
在表达式内部进行评估,它将返回您所期望的:
>> ({} + [])
"[object Object]"
另一个有趣的事情是,您不能以对象字面量开始语句,因为解释器会尝试将其解析为语句。这样做
{ "object": "literal" };
会抛出语法错误。
因为{}
被视为一个块。因此,您的陈述实际上是:
{
//empty block here
}
+[] //0 same as Number([])
这就是为什么这是无效的javascript:
eval('{hello: "world", key: "value"}') //Syntax error
您可以添加 () 使其成为表达式(块不能在表达式中使用,因此它将成为对象初始化器:
eval('({hello: "world", key: "value"})') //Object
空块被强制为零。然后+
操作员决定将其强制[]
为一个数字。