为啥 chrome 控制台在 + 和 + 之间给出不同的结果;

Posted

技术标签:

【中文标题】为啥 chrome 控制台在 + 和 + 之间给出不同的结果;【英文标题】: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 如下:

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

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

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

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

【问题讨论】:

"...几乎总是有一个合乎逻辑的解释"取决于您如何定义“逻辑”。总是有一个一致的解释,即使这种一致性被本地化为特定的实现。 您可以通过忽略与+ 运算符有关的任何事情来简化您的注意力。您可以通过; 之间的区别重现一个更简单的情况,其中; 产生undefined。因此,您的+ 案例很可能被视为 + undefined,因此NaN。不是一个完整的解释,但至少你知道你可以排除 + 的原因。 @Chase 见2ality.com/2012/01/object-plus-object.html 【参考方案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 控制台必须以某种方式进行该调用。 感谢您的回答。我有点希望有人能提出完全合理的解释,但我想既然没有控制台规范,那么它只会取决于实现,所以它只能让我们猜测。

以上是关于为啥 chrome 控制台在 + 和 + 之间给出不同的结果;的主要内容,如果未能解决你的问题,请参考以下文章

为啥我不能在 chrome 控制台中展开这个事件对象?

为啥 Chrome 控制台中的 + 不再是 NaN?

为啥 javascript 对象在 Chrome、Firefox、Safari 的控制台中显示不同的值? [复制]

为啥可以在 Chrome 的 devtools 控制台中重新声明“让”? (其他浏览器不允许。)

为啥vue-devtools chrome插件安装完成了,但是控制台没有显示出来

为啥 Google Chrome 将相同的 console.log 消息分组?