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