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

Posted

技术标签:

【中文标题】为啥 Chrome 控制台中的 + 不再是 NaN?【英文标题】:Why is + no longer NaN in Chrome console?为什么 Chrome 控制台中的 + 不再是 NaN? 【发布时间】:2016-07-26 01:59:41 【问题描述】:

我今天注意到,当您在控制台中输入 + 时,Chrome 49 不再输出 NaN。相反,它输出字符串[object Object][object Object]

这是为什么?语言有变化吗?

【问题讨论】:

看起来 chrome 现在将此操作视为字符串连接而不是加法。为什么,我不知道,这就是为什么这是评论而不是答案:) 试试var e = ; e.toString(),你会明白我的意思 “语言变了吗?”没有。 @FelixKling 语言改变吗? ...不。 :c 注意eval('+')eval('(+)')继续分别返回NaN"[object Object][object Object]"的预期结果。不,语言没有改变。 也许WATMAN 与它有关? 【参考方案1】:

Chrome 开发工具现在会自动将所有以 开头并以 结尾的内容包装在一对隐式括号 (see code) 中,以强制将其评估为表达式。这样, 现在会创建一个空对象。如果你回顾历史()可以看到这一点,上一行将包含在(…)中。

为什么? 我不知道,但是我猜它可以减少不了解块与对象文字的新手的困惑,如果你只是想评估一个表达。

事实上这就是原因,正如bug 499864 中所讨论的那样。纯粹的方便。因为还有node REPL had it (see code)。

【讨论】:

愚蠢的 Chrome,a:1),(b:2 应该抛出一个错误,而不是产生一个对象。 当你使用正则表达式***.com/questions/1732348/…解析任意深度的嵌套结构时会发生这种情况 我不知道为什么,但不知何故,当我在那里看到我的消息时,我觉得“有名”,尽管该页面与此页面一样公开 :D 奇怪的 *** 问题。这是我关于这个问题的旧答案***.com/questions/17268468/… 我不喜欢当前的实现并计划修复它。 bugs.chromium.org/p/chromium/issues/detail?id=499864#c17 @Zirak 祝你好运修复这些垃圾,IMO 应该尽快取消它。但是,如果您想改进它,请考虑在插入的 ) 之前添加一个换行符,以防它在评论中,例如a:3 // :- 可能仍会产生一个对象。【参考方案2】:

如果您在检查后点击向上箭头,您会注意到显示 ( + ) 而不是 + ,这会导致 "[object Object][object Object]"

相比之下,在 Firefox 中, + 仍然显示 NaN,但如果您使用 ( + ),它也会显示 "[object Object][object Object]"

所以,Chrome 似乎在看到这个操作时会自动添加括号。

【讨论】:

这个答案是正确的。但是哇,伙计,我不确定我是否喜欢 chrome 这样做。糟糕的谷歌。 @sgroves 我很想看看这在 Canary 中是否相同,以及它是故意完成的还是实际上是一个错误。 + 未“清理”为( + ) 时被视为+ ,因为 被解析为空块。 为什么它首先会返回 NaN? @0x499602D2:因为除非您执行括号(或以其他方式导致解析器转换为期望表达式而不是语句),否则初始 只是一个空代码块并且被忽略,离开我们使用+,它是一个一元+ 和一个空对象初始化器。 + 会将其参数强制转换为数字,这涉及将对象转换为原语(在这种情况下最终将成为toString,导致"[object Object]"),因此我们得到+"[object Object]",即@987654339 @ 因为"[object Object]" 无法转换为有效数字。【参考方案3】:

关于控制台的 Chrome 54:

不幸的是,我自己添加了 Clippy 引用。控制台没有提供关于它为你做了什么的信息。

新规则非常简单,省去了在将 Object Literals 粘贴到控制台之前费力地输入这两个困难字符 o=0, 的麻烦:

如果您的代码以:可选空格(不允许 cmets)开头,后跟 ; 并且该代码可以被解释为一个对象; 并且该对象后面没有其他代码,除非: 第一个对象之后的代码是二元运算符, 那么可以有任意多的操作,包括分组 前提是最后一个运算符在右手位置有一个 Object 字面量; 并且最终的 Object 没有被分组到括号中 并且该代码没有以分号结尾 并且代码后面没有 cmets(允许内部 cmets,只要它们不在初始或最终位置) 只有这样,您的 javascript(实际上可能是也可能不是有效代码)才会被重新引入为有效对象。您不会被告知您的代码已被重新​​解释。

wat:1),(wat:2终于又报错了。

let i=0;var increment=_=>i++ 最后是正确允许的,这是一种很好的闭包方式。

但是,下面的错误是一个对象,这就像@Bergi所说的方便,它解释JS错误来帮助你!规范说它是一个带有标签语句“foo”的块,其字面量为 1,没有分配给任何东西。

foo:1

上面应该是一样的

if(1) 
    foo: 1

以下内容被正确处理为块...因为它前面有注释!

//magic comment
foo:1

是这样的:

foo:1
//also magic

这是一个对象:

foo:
//not so magic comment
1

这是一个错误

//not so magic comment
foo:1.foo

是这样的:

foo:1.foo

这很好:

1..wat

undefined

原来如此:

['foo'][0]

下一个被正确解释为带有0, 的表达式位置的对象,这通常是我们明确确保我们使用表达式而不是语句的方式。

0,foo:1.foo

我不明白他们为什么将值包装在括号中。 JS 有一些荒谬的设计决定,但试图让它在这种情况下表现得更好并不是一个真正的选择,控制台需要正确运行 JS,我们需要确信 chrome 不仅仅是猜测它认为我们真正的意思是做其他事情。

如果你不喜欢逗号操作符,你可以使用赋值

x = foo:1.foo

因为现在

 +  + 

"[object Object][object Object][object Object]"

; +  + 

"NaN[object Object]"

我可以处理疯狂和一致...疯狂和不一致不,谢谢!

【讨论】:

REPL 不是语言,它是 REPL。它将字符串传递给语言除其他外。 Here's several things the Chrome REPL does the language itself does not。它们非常有用,所以我很高兴它们没有只使用简单的语言。 @gman A REPL 读取一个字符串,评估它,打印结果,然后准备读取下一段动态代码。链接页面中的任何内容都不是无效的 JavaScript。范围为控制台上下文的“$_”变量显然是一种方便,仅在 REPL 中才有意义。尽管如此,“$_”是一个有效的变量名,其余的只是普通的函数和使用普通 JavaScript 调用的类。 不知道你的意思是什么。我的观点是语言是一回事,它运行的环境是另一回事。您在回答中举了一个例子。在 JS 中 foo:1foo:1// 产生相同的东西。在 Chrome JS REPL 中他们没有。 REPL 所做的不仅仅是评估 JS。它正在处理字符串并决定处理不同的事情。 var x = eval('a:1') 在有效的 JavaScript 中 x 现在是 1,而不是更直观的对象 a:1。是的,这很奇怪,但你不能因为它做了奇怪的事情就改变语言。 JSON 字符串以外的所有内容都被解释为 JavaScript 并进行评估。在粘贴 JSON 之前键入 0, 并不困难,或者我很高兴收到警告,即为方便起见,字符串被解释为对象而不是 JavaScript。

以上是关于为啥 Chrome 控制台中的 + 不再是 NaN?的主要内容,如果未能解决你的问题,请参考以下文章

为啥Mac下了chrome谷歌浏览器却无法访问网站?

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

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

为啥chrome浏览器经常更换端点

为啥在开发控制台启动时我在 Chrome 中获得更好的性能?

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