我們都知道javascript在測試相等性時會做出時髦的轉換,但是在引擎蓋下究竟發生了什麼?如果[0] == 0和0 == [[0]]都爲真,爲什麼[0] == [[0]]爲false?
> [0] == 0
true
> 0 == [[0]]
true
> [0] == [[0]]
false
是的,我很期待從==運算符的傳遞性。
我們都知道javascript在測試相等性時會做出時髦的轉換,但是在引擎蓋下究竟發生了什麼?如果[0] == 0和0 == [[0]]都爲真,爲什麼[0] == [[0]]爲false?
> [0] == 0
true
> 0 == [[0]]
true
> [0] == [[0]]
false
是的,我很期待從==運算符的傳遞性。
[0] == 0
和0 == [[0]]
將原始值與對象進行比較,因此將執行類型轉換。在兩種情況下,[0]
和[[0]]
最終都將轉換爲原始值0
。
這在步驟中定義8(和圖9)的The Abstract Equality Comparison Algorithm:
- 如果Type(x)是String或數目和類型(y)爲對象,
返回比較結果x == ToPrimitive(y)。
然而,[0] === [[0]]
比較兩個對象和兩個不同的對象是從不彼此相等:
1F。如果x和y指的是同一個對象,則返回true。否則,返回false。
這裏有一個稍微假笑的例子,說明了鬆散的比較是不傳遞的:
" " == 0 // true
"\n" == 0 // true
" " == "\n" // false
前兩個比較進行類型轉換(串號),最後一個不和兩個字符串的值是不同的。
你的第一個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
上@KooiInc的answer在a comment提到@JanDvorak,背後場景,JS不使用toString
進行此轉換。然而,在概念上這是發生了什麼。
行爲是作爲每JavaScript的The Abstract Equality Comparison Algorithm
匹配的算法中案例9:類型(X )是對象和類型(y)是字符串 或數字
結果:ToPrimitive(x)== y。即 '0' == 0,因此真
匹配算法的案例8:如果類型(x)是字符串或數字,類型(y)是對象,則 結果:x == ToPrimitive(y)。即,0 == '0',因此真
匹配算法的案例1:類型(x)與類型(y)相同, 如果類型爲'object',如果x和y指的是同一個對象,則返回true。否則,返回false。 即參考將匹配,因此虛假
「是的,我期望從==操作符的傳遞性是天真的。」 - 確實。有很多例子 –
只是一個側面說明,也讀這個:http://stackoverflow.com/questions/7202157/why-is-10這幫助了我很多理解爲什麼這些條件是真的,假的,1, 0或其他。 – briosheje
相關:http://stackoverflow.com/q/22231191/1048572 – Bergi