【问题标题】:Why does {} + [] return 0 in Javascript? [duplicate]为什么 {} + [] 在 Javascript 中返回 0? [复制]
【发布时间】:2012-08-09 23:05:32
【问题描述】:

可能重复:
What is the explanation for these bizarre JavaScript behaviours mentioned in the 'Wat' talk for CodeMash 2012?

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

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

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

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

>> {} + []
0

什么可能导致它返回0

【问题讨论】:

  • 看起来您正在将 null 添加到 null。这相当于 0 + 0。不过这只是猜测。
  • @Trisped:这些都不为空。
  • 这个问题被stackoverflow.com/questions/9032856/… 所包含(截至目前有301票).....
  • 有人在看destroyallsoftware的“Wat”吗? :P

标签: javascript


【解决方案1】:

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

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

语句在结束大括号} 之后结束,这意味着接下来的三个字符+[] 构成了它们自己的语句。

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

所以+[]Number([]) 相同,计算结果为0

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


话虽如此,如果您在表达式中评估{} + [] ,它将返回您所期望的:

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

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

{ "object": "literal" };

会抛出语法错误。

【讨论】:

  • 有趣的是,如果您在属性名称上省略引号,则具有单个属性的对象文字在语句开头并不是语法错误。这并不意味着它看起来像它所做的那样。例如,{ object: "literal" } 被解释为带有单个语句 "literal" 的块语句。 object 成为语句的标签。
  • @MatthewCrumley 那是因为object: 被视为一个标签(您可以与 break 语句一起使用的标签)
  • @彼得奥尔森。我很欣赏你的回应。但是,表达式{ "object": "literal" }; 只会在 Firefox 中引发错误。 Chrome 将其视为对象字面量。
【解决方案2】:

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

{

//empty block here
}

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

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

eval('{hello: "world", key: "value"}') //Syntax error

您可以添加 () 使其成为表达式(块不能在表达式中使用,因此它将是对象初始化器:

eval('({hello: "world", key: "value"})') //Object

【讨论】:

  • 对我来说这个答案有什么问题并不是很明显,所以请解释一下反对意见。
  • +1 抵消反对票。你早了大约 25 秒,我认为你的多行示例更清晰
【解决方案3】:

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

【讨论】:

  • 空块是空块,它不会被强制任何东西。
  • @alex,你是对的,在阅读了彼得奥尔森的回答后,我明白唯一的强制是将数组转换为一个数字,第一组括号被忽略,最后一条语句被返回
猜你喜欢
  • 2019-12-15
  • 1970-01-01
  • 1970-01-01
  • 2017-06-13
  • 1970-01-01
  • 2020-12-11
  • 1970-01-01
  • 2011-01-09
  • 2020-03-25
相关资源
最近更新 更多