JavaScript 抽象相等/不等式和类型转换

示例

问题

如果操作数类型不匹配,则抽象的相等和不相等运算符(==和!=)将转换其操作数。这种强制性是导致人们对这些运算符的结果产生混淆的常见原因,特别是,这些运算符并不总是像人们期望的那样可传递的。

"" ==  0;     // 真A
 0 == "0";    // 真A
"" == "0";    // 假B
false == 0;   // 真正
false == "0"; // 真正

"" !=  0;     // 假A
 0 != "0";    // 假A
"" != "0";    // 真正 B
false != 0;   // 假
false != "0"; // 假

如果考虑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);        // 真正;
test("0", 0);       // 真正
test("", "0");      // 真正;
test("abc", "abc"); // 假As operands are not numbers

或者,如果您想要字符串比较:

var test = (a,b) => String(a) == String(b);
test("", 0);   // 假;
test("0", 0);  // 真正
test("", "0"); // 假;

边注:Number("0")和new Number("0")是不是一回事!前者执行类型转换时,后者将创建一个新对象。对象通过引用而不是值进行比较,这解释了以下结果。

Number("0") == Number("0");         // 真正;
new Number("0") == new Number("0"); // 假

最后,您可以选择使用严格的相等和不相等运算符,它们将不执行任何隐式类型转换。

"" ===  0;  // 假
 0 === "0"; // 假
"" === "0"; // 假

可以在以下位置找到对该主题的进一步参考:

JavaScript比较中应使用哪个等于运算符(== vs ===)?

抽象平等(==)