为什么 {} + {} 在 Chrome 控制台中不再是 NaN?

IT技术 javascript google-chrome
2021-01-24 08:26:01

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

为什么是这样?语言变了吗?

3个回答

Chrome devtools 现在会自动将所有以隐式括号开头{和结尾的内容包装起来}请参阅代码),以强制将其计算为表达式。这样,{}现在创建一个空对象。如果您返回历史记录 ( ),您可以看到这一点,前一行将包含在(…).

为什么?我不知道,但我猜它可以减少不了解块与对象字面量的新手的混淆,而且如果您只想评估表达式,它也会更有帮助。

事实上,这就是原因,正如错误 499864 中所讨论的那样纯粹的方便。并且因为节点 REPL 也有它见代码)。

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

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

相比之下,在 Firefox 中,{} + {}仍然显示NaN,但如果你这样做({} + {})也会显示"[object Object][object Object]"

所以,看起来 Chrome 在看到这个操作时会自动添加周围的括号。

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

从 Chrome 54 开始,关于控制台:

📎-“我为您将该块转换为对象”-Clippy 不幸的是,我自己添加了 Clippy 引用。控制台没有提供有关它为您所做的工作的信息。

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

  • 如果您的代码以以下开头:可选空格,(不允许注释)后跟{;
  • 并且该代码可以被解释为一个对象;
  • 并且该对象后面没有其他代码,除非:
  • 第一个对象后面的代码是一个二元运算符,
  • 然后可以有任意多的操作,包括分组
  • 前提是最后一个运算符在右手边有一个对象字面量;
  • 并且最终对象尚未分组在括号中
  • 并且该代码不以分号结尾
  • 并且代码后面没有注释(允许内部注释,只要它们不在初始或最终位置)
  • 然后并且只有到那时,您的 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]

下一个被正确解释为用 a 重击到表达式位置的对象,0,这通常是我们如何明确地确保我们有一个表达式而不是一个语句。

0,{foo:1}.foo

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

如果您不喜欢逗号运算符,则可以使用赋值

x = {foo:1}.foo

因为就目前而言

{} + {} + {}

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

;{} + {} + {}

"NaN[object Object]"

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

@gman A REPL 读取字符串,对其求值,打印结果,然后准备读取下一段动态代码。链接页面中的任何内容都不是无效的 JavaScript。作用域为控制台上下文的“$_”变量显然是一种便利,只有在 REPL 中才有意义。尽管如此,“$_”是一个有效的变量名,其余的只是用普通 JavaScript 调用的普通函数和类。
2021-03-19 08:26:01
REPL 不是 REPL 的语言。它将字符串传递给语言等等以下是 Chrome REPL 语言本身没有做到的几件事它们非常有用,所以我真的很高兴它们没有只使用简单的语言。
2021-03-20 08:26:01
不确定你的观点是什么。我的观点是语言是一回事,它运行的环境是另一回事。你在回答中举了一个例子。在JS{foo:1}{foo:1}//生产同样的事情。在 Chrome JS REPL 中,他们没有。REPL 所做的不仅仅是评估 JS。它正在处理字符串并决定做不同的事情。
2021-03-26 08:26:01
var x = eval('{a:1}')在有效的 JavaScript 中,x 现在是 1,而不是更直观的对象 {a:1}。是的,这很奇怪,但你不能仅仅改变语言,因为它做了奇怪的事情。JSON 字符串以外的所有内容都被解释为 JavaScript 并进行评估。0,在粘贴 JSON 之前输入并不困难,或者我会很高兴收到警告,即为了方便起见,字符串被解释为对象而不是 JavaScript。
2021-04-09 08:26:01