为啥 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,
的麻烦:
;
并且该代码可以被解释为一个对象;
并且该对象后面没有其他代码,除非:
第一个对象之后的代码是二元运算符,
那么可以有任意多的操作,包括分组
前提是最后一个运算符在右手位置有一个 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:1
和 foo:1//
产生相同的东西。在 Chrome JS REPL 中他们没有。 REPL 所做的不仅仅是评估 JS。它正在处理字符串并决定处理不同的事情。
var x = eval('a:1')
在有效的 JavaScript 中 x 现在是 1,而不是更直观的对象 a:1。是的,这很奇怪,但你不能因为它做了奇怪的事情就改变语言。 JSON 字符串以外的所有内容都被解释为 JavaScript 并进行评估。在粘贴 JSON 之前键入 0,
并不困难,或者我很高兴收到警告,即为方便起见,字符串被解释为对象而不是 JavaScript。以上是关于为啥 Chrome 控制台中的 + 不再是 NaN?的主要内容,如果未能解决你的问题,请参考以下文章
为啥 chrome 控制台在 + 和 + 之间给出不同的结果;