基本觀念
等號比較運算子(Equality operators)分為一般相等比較(Abstract Equality Comparison)及嚴格相等比較(Strict Equality Comparison)。
在等號比較中運算中一般相等比較(==)遵守強制轉換(coercion),而嚴格相等比較(===)則不遵守強制轉換。
◎ 當x是primitive type,而y是Object type時,x == ToPrimitive(y)
10 == [10] //true
"10" == [10] //true
10n == [10] //true
"0" == false //true
◎ 當x是Number,而y是String時,x == ToNumber(y)
10 == "10" //true
◎ 在一般相等比較(==)時undefined與null相等;
◎ 在嚴格相等比較(===)時undefined等於自己,null也只等於自己。
null == undefined //true
null === undefined //false
◎ boolean會被強制轉換(coercion)為Number類型
0 == false //true
"1" == true //true
true == 100 //false
◎ 當BigInt 與 Number比較時,任一邊為NaN、+∞、-∞回傳false,如果不是則比較數學值。
1n == NaN //false
100n == "100" //true
例外的情況:
◎ NaN 不等於任何值,包括自己,因此:
NaN === NaN //false
◎ 零值相等,比較+0 與 -0結果為:
+0 === -0 //true
◎ 如果object type(object、array、function)是call by reference至相同記憶體位置,則他們相等:
var a = {weather : "sunny"};
var b;
b = a;
console.log(a) //sunny
console.log(b) //sunny
b === a //true
◎ 反之,如果不在同一個記憶體中,就算value一樣,也不成立相等。
var a = {weather : "sunny"};
var b;
var b = a;
a = {weather : "sunny"}; //實字物件
console.log(a); //sunny
console.log(b); //sunny
b === a //false
用實字物件的方式另存一個獨立的記憶體,詳情可見:Javascript學習筆記01 - Primitive type v.s. Object type
Javascript迷因(meme)
拆解:
- 因為String轉換成Number,故0 == 0
0 == "0" //true
- 因為empty array(object type)轉為empty string(primitive type),故[]轉變成"",而""是String再轉換為Number,故""為0,最後0 == 0成立!
0 == [] //true
- 按照的解釋,[]轉為""(String),"0"與""皆為String,所以Javascript不會再強制轉換類型了,故"0" != []
"0" == [] //false
參考資料:
01. You Don't Know JS: Types & Grammar
02. The Best JavaScript Meme I've Ever Seen, Explained in detail
03. Equality comparisons and sameness
04. 「==」 & 「===」 運算子
05. [27] 強制轉型 - 寬鬆相等 ( == ) vs. 嚴格相等 ( === )