抽象的相等不相等和型別轉換
問題
如果運算元型別不匹配,抽象等式和不等式運算子(==
和 !=
)將轉換它們的運算元。這種型別的強制是這些運算子結果混淆的常見原因,特別是這些運算子並不總是像人們期望的那樣傳遞。
"" == 0; // true A
0 == "0"; // true A
"" == "0"; // false B
false == 0; // true
false == "0"; // true
"" != 0; // false A
0 != "0"; // false A
"" != "0"; // true B
false != 0; // false
false != "0"; // false
如果你考慮 JavaScript 如何將空字串轉換為數字,結果就會有意義。
Number(""); // 0
Number("0"); // 0
Number(false); // 0
解決方案
在語句 false B
中,兩個運算元都是字串(""
和 0
),因此不會有型別轉換,因為 ""
和 0
不是相同的值,"" == "0"
就像預期的那樣是 false
。
消除意外行為的一種方法是確保始終比較相同型別的運算元。例如,如果你希望數值比較的結果使用顯式轉換:
var test = (a,b) => Number(a) == Number(b);
test("", 0); // true;
test("0", 0); // true
test("", "0"); // true;
test("abc", "abc"); // false as operands are not numbers
或者,如果你想要字串比較:
var test = (a,b) => String(a) == String(b);
test("", 0); // false;
test("0", 0); // true
test("", "0"); // false;
旁註 :Number("0")
和 new Number("0")
不是一回事! 前者執行型別轉換,後者將建立一個新物件。物件通過引用而不是值進行比較,這解釋了下面的結果。
Number("0") == Number("0"); // true;
new Number("0") == new Number("0"); // false
最後,你可以選擇使用嚴格的相等和不等式運算子,這些運算子不會執行任何隱式型別轉換。
"" === 0; // false
0 === "0"; // false
"" === "0"; // false
可在此處找到對此主題的進一步參考: