2

如果我在 Chrome 控制台中输入

{} + {}我明白了"[object Object][object Object]"

但是如果我添加分号,结果会有所不同:

{} + {};我明白了NaN

我不明白其中的区别。第一个是有道理的,对我来说,加法运算符规则如下:

  1. 如果至少一个操作数是对象,则将其转换为原始值(字符串、数字或布尔值);
  2. 转换后,若至少有一个操作数为字符串类型,则将第二个操作数转换为字符串并执行拼接;
  3. 在其他情况下,两个操作数都转换为数字并执行算术加法。

由于两个操作数都是对象,因此它们都被转换为字符串。但是在第二种情况下发生了什么?

如果我分配一个值(a = ...)在这两种情况下,我的变量都将是一个字符串。我试图寻找在给出表达式时 Chrome 控制台返回的规范,但没有找到。奇怪的是,添加评论也会返回NaN{} + {} //comment=>NaN

我知道 Javascript 有时可能很奇怪,但几乎总是有一个合乎逻辑的解释。这里似乎取决于 Chrome 是如何解释它的。另一方面,FirefoxNaN两种情况都返回,我也不明白。

4

1 回答 1

3

我相信不同之处在于 Chrome 控制台如何解释您的代码:

这是一个表达式:

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

这是一个“程序”:

{} + {};

请注意,只要那是您的“完整程序”NaN就可以实现:{} + {}

在此处输入图像描述

以下是 Axel Rauschmayer 博士在“什么是 JavaScript 中的 {} + {}?”中所说的。

问题在于 JavaScript 将第一个 {} 解释为空代码块并忽略它。因此,NaN 是通过计算 +{}(加上后跟第二个 {})来计算的。

所以在{} + {};NaN来自评价+{}。(第一个{}被忽略。)

第一个{}作为代码块在这个例子中更明显:(在你的命令行中试试这个)

{ while (false) x++ } + {}
//=> NaN

如果 JS 被{ while (false) x++ }视为一个对象,它会抛出一个语法错误。但它不是,在这种情况下它必须是一个代码块;它忽略它并评估+{}yielding NaN

因此,要“强制” JS 将其{}视为对象而不是代码块,您可以将它们包装在 () 中。在您的 Chrome 控制台中尝试此操作:

({}) + ({});
//=> "[object Object][object Object]"

({} + {});
//=> "[object Object][object Object]"
于 2020-05-25T20:42:49.473 回答