【问题标题】:{} - 0 VS ({} - 0) in JavaScript [duplicate]{} - JavaScript 中的 0 VS ({} - 0) [重复]
【发布时间】:2018-01-20 11:19:36
【问题描述】:

在 Chrome JavaScript 控制台中,为什么将语句 {} - 0 括在括号中会更改返回值?

{} - 0    // Returns -0
({} - 0)  // Returns NaN

将单个语句括在括号中会改变包含的值,这似乎非常奇怪。我在这里错过了什么?

【问题讨论】:

  • 问得好,肯定还有其他人比我知识渊博得多。我猜这与您将其包装在括号中这一事实有关,这使其成为一个可自执行的函数?
  • 被视为空块,与空对象
  • @JoeHawkins 呵呵,我以前看过 WAT 的演讲。它实际上启发了我玩一些奇怪的表情。
  • 一方面我想 +1 这个...另一方面我想把它投反对票...

标签: javascript type-conversion


【解决方案1】:

{} - 0 行有两种可能的解释:

  1. 可以解释为{}; -0,其中{}被解释为空块语句,-是一元否定运算符(所以-0只是“负零”)。评估时 this 的值是最后一条语句的值,即 -0。
  2. 可以解释为({} - 0),其中{}被解释为空对象,-是减法运算符(所以0是从{}中减去的)。

在您的第一行中,这是模棱两可的,因此它将选择第一种解释。在第二行中,第一种解释是无效的(因为块语句永远不能成为表达式的一部分,这是你用括号强制的)。

【讨论】:

  • 这是一个非常有趣的问题。不是 OP,但我对此有后续跟进:如果您通过添加方法或属性来强制将 {} 解释为对象怎么办?这适用于括号,但并非没有。 (例如,带括号时,此表达式的计算结果为 3({valueOf:()=>3} - 0),但不带括号时,它仍会在控制台中返回 -0{valueOf:()=>3} - 0)。添加的方法不应该强制它在那时将{ .. } 解释为一个对象,然后尝试将其评估为减法吗?
  • @JosephMarikle 我认为同样的推理在这里仍然适用,没有括号,它仍然可以解释为{valueOf:()=>3}; -0 但是({valueOf:()=>3}; -0) 是一个语法错误。
  • @JosephMarikle 你会这么认为,但不是:valueOf: 在这种情况下是 label statement(一个罕见的 JavaScript 功能),在声明 () => 3; 之前,所以它仍然被解释为一个块语句而不是对象。它的解释方式与{ valueOf: () => 3; }; -0 相同。
  • @JosephMarikle 但是,如果添加多个属性,它就不能再是块语句了:{ a: 1, b: 2 } 不能是块语句,因为标签语句不能出现在逗号之后(因为它们不能是表达式的一部分)。
  • @Frxstrem 这太有趣了。感谢您的解释。有趣的是,在使用第二个属性/方法强制对象之后,它只会引发语法错误(至少在 Chrome 中)。 {valueOf:()=>3,a:0} - 0.
【解决方案2】:

{} - 0:这里的{}只是一个空块,什么都不做,所以-0由控制台返回。

({} - 0):这里{}是表达式的一部分,被转换为数字。在该空对象中没有定义valueOf() 方法,并且在转换为数字时,它回退到toString() 方法,该方法返回类似object Object{}。然后这个字符串object Object 被转换成一个数字并给出NaN,因为它实际上不是一个数字。所以,我们有

({} - 1) -> ('object Object' - 1) -> (NaN - 1)

所有带有NaN 的东西都会给出NaN。这就是您最终在控制台中看到的内容。

【讨论】:

    【解决方案3】:
    {} - 0
    

    被解释为:{} empty block statement- 0 negative zero

    ({} - 0)
    

    () 中的所有内容都被解释为表达式,empty object - 0 = NaN

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-08-08
      • 1970-01-01
      • 1970-01-01
      • 2014-03-31
      • 2015-09-07
      • 2012-05-30
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多