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

Dan*_*iel 34 javascript

可能重复:
CodeMash 2012的"Wat"演讲中提到的这些奇怪的JavaScript行为的解释是什么?

我知道当[]被强制转换为字符串时它返回空字符串(""),并且当{}被强制转换为字符串时它返回"[object Object]".

当我[] + {}在浏览器的Javascript控制台中运行时,它会像我期望的那样返回:

>> [] + {}
"[object Object]"
Run Code Online (Sandbox Code Playgroud)

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

>> {} + []
0
Run Code Online (Sandbox Code Playgroud)

什么可能导致它返回0

Pet*_*son 55

如果{在语句的开头有一个,它将被解释为一个块,它可能包含零个或多个语句.其中没有语句的块将具有空的延续值.

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

该语句在结束括号后结束},这意味着接下来的三个字符+[]包含它们自己的语句.

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

所以+[]Number([])评估相同0.

简而言之,{} + []是一个空代码块,后跟一个强制转换为数字的数组.


总而言之,如果你{} + [] 在表达式中进行评估,它将返回你所期望的:

>> ({} + []) 
"[object Object]" 
Run Code Online (Sandbox Code Playgroud)

另一个有趣的事情是你不能用对象文字开始一个语句,因为解释器会尝试将它解析为一个语句.这样做

{ "object": "literal" };
Run Code Online (Sandbox Code Playgroud)

会抛出语法错误.

  • 有趣的是,如果您在属性名称上留下引号,则具有单个属性的对象文字在语句开头不是语法错误.它并不意味着它的样子.例如,`{object:"literal"}`被解释为带有单个语句的块语句,``literal"`.`object`成为声明的标签. (4认同)

Esa*_*ija 19

因为{}被视为一个块.因此,您的陈述实际上是:

{

//empty block here
}

+[] //0 same as Number([])
Run Code Online (Sandbox Code Playgroud)

这就是为什么这是无效的javascript:

eval('{hello: "world", key: "value"}') //Syntax error
Run Code Online (Sandbox Code Playgroud)

你可以添加()使它成为一个表达式(块不能在表达式中使用,所以它将是对象初始化器:

eval('({hello: "world", key: "value"})') //Object
Run Code Online (Sandbox Code Playgroud)

  • 对我来说,这个答案有什么问题并不是很明显,所以请解释一下downvote. (2认同)
  • +1抵消downvote ..你提前约25秒,我认为你的多线示例更清晰 (2认同)