2014-12-30 105 views
6

我们都知道javascript在测试相等性时会做出时髦的转换,但是在引擎盖下究竟发生了什么?如果[0] == 0和0 == [[0]]都为真,为什么[0] == [[0]]为false?

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

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

+1

“是的,我期望从==操作符的传递性是天真的。” - 确实。有很多例子 –

+0

只是一个侧面说明,也读这个:http://stackoverflow.com/questions/7202157/why-is-10这帮助了我很多理解为什么这些条件是真的,假的,1, 0或其他。 – briosheje

+0

相关:http://stackoverflow.com/q/22231191/1048572 – Bergi

回答

7

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

这在步骤中定义8(和图9)的The Abstract Equality Comparison Algorithm

  • 如果Type(x)是String或数目和类型(y)为对象,
    返回比较结果x == ToPrimitive(y)。
  • 然而,[0] === [[0]]比较两个对象和两个不同的对象是从不彼此相等:

    1F。如果xy指的是同一个对象,则返回true。否则,返回false。


    这里有一个稍微假笑的例子,说明了松散的比较是不传递的:

    " " == 0 // true 
    "\n" == 0 // true 
    " " == "\n" // false 
    

    前两个比较进行类型转换(串号),最后一个不和两个字符串的值是不同的。

    2

    你的第一个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 
    

    @KooiIncanswera comment提到@JanDvorak,背后场景,JS不使用toString进行此转换。然而,在概念上这是发生了什么。

    1

    行为是作为每JavaScript的The Abstract Equality Comparison Algorithm

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

    匹配的算法中案例9:类型(X )是对象和类型(y)是字符串 或数字
    结果ToPrimitive(x)== y。即 '0' == 0,因此

  • 比较0 == [[0]] - 操作数的类型是不同
  • 匹配算法的案例8:如果类型(x)是字符串或数字,类型(y)是对象,则 结果:x == ToPrimitive(y)。即,0 == '0',因此

  • 比较[0] == [[0]] - 操作数的类型是相同的,即对象
  • 匹配算法的案例1:类型(x)与类型(y)相同, 如果类型为'object',如果x和y指的是同一个对象,则返回true。否则,返回false。 即参考将匹配,因此虚假