【问题标题】:Why does chrome console gives a different result between {} + {} and {} + {};为什么 chrome 控制台在 {} + {} 和 {} + {} 之间给出不同的结果;
【发布时间】:2020-09-12 13:00:48
【问题描述】:

如果我在 Chrome 控制台中输入

{} + {}我得到"[object Object][object Object]"

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

{} + {};我得到NaN

虽然我不明白其中的区别。第一个是有道理的,对我来说,addition operator rules 如下:

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

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

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

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

【问题讨论】:

  • "...几乎总是有一个合乎逻辑的解释"取决于您如何定义“逻辑”。总是有一个一致的解释,即使这种一致性被本地化为特定的实现。
  • 您可以通过忽略与+ 运算符有关的任何事情来简化您的注意力。您可以通过{}{}; 之间的区别重现一个更简单的情况,其中{}; 产生undefined。因此,您的+ 案例很可能被视为{} + undefined,因此NaN。不是一个完整的解释,但至少你知道你可以排除 + 的原因。

标签: javascript console google-chrome-devtools google-chrome-console


【解决方案1】:

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

这是一个表达式:

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

这是一个“程序”:

{} + {};

请注意,NaN 可以通过 {} + {} 实现,如果那是您的“完整程序”:

这是 Axel Rauschmayer 博士在 "What is {} + {} in JavaScript?" 中所说的

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

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

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

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

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

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

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

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

【讨论】:

  • 为什么{} +1({} +1) 不返回相同的值呢?第一种情况也应该返回一个字符串,因为它是一个表达式。
  • @Ricola 我认为这是因为在{} + 1 中,该对象被视为代码块并被忽略而产生1。在第二个示例中,由于您不能在括号中包含代码块,因此它必须是一个对象。因此它被转换成一个字符串并添加到“1”之前。在{} + {} 中,引擎可能得出结论,将两个代码块连接起来毫无意义,因此会威胁到这两个对象作为对象。
  • 您知道Chrome控制台返回的内容是否有任何规范吗?例如,你怎么知道一个被视为表达式而另一个被视为“程序”?
  • @Ricola 我不知道。但是我确实知道表达式是可以传递的。例如10 + 10 是一个表达式。您可以将其分配给变量或将其传递给函数按原样。而var x = 10 + 10; 是一个声明;你不能做foo(var x = 10 + 10); 用于分隔语句,因此如果有意义,Chrome 控制台必须以某种方式进行该调用。
  • 感谢您的回答。我有点希望有人能提出完全合理的解释,但我想既然没有控制台规范,那么它只会取决于实现,所以它只能让我们猜测。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2020-09-03
  • 2013-08-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-04-29
  • 2021-12-07
相关资源
最近更新 更多