如果[0] == 0和0 == [[0]]都为真,那么为什么[0] == [[0]]为假?

时间:2014-12-30 10:19:58

标签: javascript

我们都知道javascript在测试相等性时会做出时髦的转换,但究竟会在幕后发生什么?

> [0] == 0
true
> 0 == [[0]]
true
> [0] == [[0]]
false

是的,我很期待从==运算符预期传递性。

3 个答案:

答案 0 :(得分:7)

[0] == 00 == [[0]]将原始值与对象进行比较,因此将执行类型转换。在这两种情况下,[0][[0]]最终都会转换为原始值0

这在The Abstract Equality Comparison Algorithm

的步骤8(和9)中定义
  
      
  1. 如果Type(x)是String或Number,Type(y)是Object,
      返回比较结果x == ToPrimitive(y)。
  2.   

但是,[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

  1. 比较 [0] == 0 - 操作数类型不同
  2.   

    匹配algo的案例9 :Type(x)是Object,Type(y)是String   或号码   结果ToPrimitive(x)== y。即'0'== 0,因此 true

    1. 比较 0 == [[0]] - 操作数类型不同
    2.   

      匹配algo的案例8 :如果Type(x)是String或Number而Type(y)是Object,      结果:x == ToPrimitive(y)。即0 =='0',因此 true

      1. 比较[0] == [[0]] - 操作数类型相同,即对象
      2.   

        匹配algo的案例1 :Type(x)与Type(y)相同,       如果type为'object',如果x和y引用同一个对象,则返回true。否则,返回false。       即引用将匹配,因此是错误的