2014-12-30 104 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。 即參考將匹配,因此虛假