为什么“[] + {} === {} + []"评估为“真实”? [英] Why does "[] + {} === {} + []" evaluate to "true"?
问题描述
如果您打开JS控制台并输入 [] + {} === {} + []
,它会告诉您这是真的。
If you open your JS console and type in [] + {} === {} + []
it tells you it's true.
我不明白为什么会这样。我试图查看它是如何解析的。
I don't understand why this is. I attempted to look up at how it's parsed.
对于 [] + {}
+
这里是加法运算符,因为操作数都是文字。 LHS不会通过 .valueOf()
生成一个数字,因此它使用 .toString()
执行字符串连接给我们的操作数 +
[object Object]
For [] + {}
the +
here is the addition operator as operands are both literals. LHS doesn't yield a number through .valueOf()
so it performs string concatenation using .toString()
on both operands giving us ""
+ "[object Object]"
对于 {} + []
{}
是一个空代码块并被忽略, +
此处的运算符被解析为一元加号运算符,它将其操作数转换为数字。转换为数字的空数组变为 0
For {} + []
the {}
is an empty code block and is 'ignored', the +
operator here is parsed as the unary plus operator, it converts its operand to a Number. Empty arrays converted to a number become 0
所以这似乎是[ object object]=== 0
肯定应该是假的?。
So this is appears to be "[object Object]" === 0
which surely should be false?.
身份运算符检查两个操作数是否相等而没有类型转换。我看不出这是怎么回事。我错过了这个故事的哪个部分?
The identity operator checks if the two operands are equal without type conversion. I can't see how this ever coud be true. What part of the story am I missing?
编辑:
我看你是否输入({} + [])
它将其解析为一个空对象,使RHS等于[object Object]。我查了一下,()
是分组运算符。那么这可能与此有关吗?
I see if you type ({} + [])
it parses it as an empty object making the RHS equal to "[object Object]". I looked this up and ( )
is the grouping operator. So perhaps this has something to do with this?
This is not a duplicate of What is the explanation for these bizarre JavaScript behaviours mentioned in the 'Wat' talk for CodeMash 2012?. Answer bullet points 1 === 2 should NOT be true.
推荐答案
第二点在这个宏伟的答案中解释了当你将一个数组和一个对象加在一起时会发生什么。
The second point in this magnificent answer explains what happens when you "add together" an array and an object.
var result = [] + {};
console.log(result);
console.log(typeof result);
你得到的是字符串 [ object Object]
因为每个参数都转换为字符串。对于一个数组,会导致在其上调用 .join()
,这反过来导致一个空字符串。对于Objects,它生成字符串[object Object]
- 将它们一起添加留下第二个字符串。
What you get is the string [object Object]
because each of the arguments is converted to a string. For an array, that results in calling .join()
on it, which in turn, results in an empty string. For Objects, it produces the string "[object Object]"
- adding them together leaves the second string.
比较的两侧也是如此 - 在右侧,顺序不同但无关紧要。结果将不与答案中的第3点相同,因为区别在于 {} + []
是在开头的该行,所以 {}
被解释为空块。在这种情况下,它(正确地)将被解释为普通对象符号)。将执行相同的转换逻辑,它将生成与以前相同的字符串:[object Object]
The same happens on both sides of the comparison - on the right hand side, the order is different but that does not matter. The result will not be the same as point 3 in the answer, for the difference is that there {} + []
is in the beginning of the line, so {}
is interpreted as an empty block. In this situation it will (correctly) be interpreted as a plain object notation). The same casting logic will be performed and it will produce the same string as before: "[object Object]"
所以,最后,你要比较[object Object]===[object Object]
,它返回 true
。
So, in the end, you are comparing "[object Object]" === "[object Object]"
which returns true
.
请注意 {} + [] === [] + {}
将 not 产生相同的 - 再次,由于链接答案的第3点 - 第一个 {}
将被解释为空块,所以左边hand side变为 + []
,它将数组转换为数字,因此比较的结果将是 false
。 然而如果您在Chrome开发工具中测试此表达式,您确实会获得 true
。这是因为 Chrome会自动换行括号中的表达式强制将初始 {}
解释为对象。在Firefox或Node REPL或其他人中检查 {} + [] === [] + {}
应该产生正确的 false
。
Note that {} + [] === [] + {}
will not produce the same - again, due to point 3 of the linked answer - the first {}
will be interpreted as an empty block, so the left hand side becomes +[]
which converts the array to a number, hence the result of the comparison will be false
. However if you test this expression in the Chrome dev tools you will indeed get true
. This is because Chrome will auto-wrap your expression in parentheses which forces the initial {}
to be interpreted as an object. Checking {} + [] === [] + {}
in Firefox or Node REPL or others should produce the "correct" false
.
这篇关于为什么“[] + {} === {} + []"评估为“真实”?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!