我们都知道javascript在测试相等性时会做出时髦的转换,但究竟会在幕后发生什么?
> [0] == 0
true
> 0 == [[0]]
true
> [0] == [[0]]
false
是的,我很期待从==运算符预期传递性。
答案 0 :(得分:7)
[0] == 0
和0 == [[0]]
将原始值与对象进行比较,因此将执行类型转换。在这两种情况下,[0]
和[[0]]
最终都会转换为原始值0
。
这在The Abstract Equality Comparison Algorithm:
的步骤8(和9)中定义
- 如果Type(x)是String或Number,Type(y)是Object,
醇>
返回比较结果x == ToPrimitive(y)。
但是,[0] === [[0]]
比较两个对象,两个不同的对象永远不会相等:
1F。如果 x 且 y 引用同一对象,则返回true。否则,返回false。
这是一个稍微简单的例子,它表明松散的比较不是传递性的:
" " == 0 // true
"\n" == 0 // true
" " == "\n" // false
前两个比较执行类型转换(字符串到数字),最后一个没有,两个字符串的值都不同。
答案 1 :(得分:2)
你的前两个例子隐式地将数组转换为字符串,然后将它们与0
进行比较:
var a = [0].toString(); // "0"
var b = a == 0 // "0" == 0; // true
最后一个例子没有投射数组,它只是比较数组'身份。
显然,这些不匹配,因此返回false
。
在您的示例中,您在某些阵列中的额外深度层并没有什么区别:
[0] == [0] // false, they're not the same array.
0 == [[[[0]]]] // true, [[[[0]]]].toString() === "0", "0" == 0
@JanDvorak a comment @KooiInc answer中提到的{{3}},在幕后,JS并没有使用toString
这种转换。但是,从概念上讲,这就是发生的事情。
答案 2 :(得分:1)
行为符合JavaScript The Abstract Equality Comparison Algorithm
匹配algo的案例9 :Type(x)是Object,Type(y)是String 或号码 结果:ToPrimitive(x)== y。即'0'== 0,因此 true
匹配algo的案例8 :如果Type(x)是String或Number而Type(y)是Object, 结果:x == ToPrimitive(y)。即0 =='0',因此 true
匹配algo的案例1 :Type(x)与Type(y)相同, 如果type为'object',如果x和y引用同一个对象,则返回true。否则,返回false。 即引用将匹配,因此是错误的