抽象的相等不相等和类型转换
问题
如果操作数类型不匹配,抽象等式和不等式运算符(==
和 !=
)将转换它们的操作数。这种类型的强制是这些运算符结果混淆的常见原因,特别是这些运算符并不总是像人们期望的那样传递。
"" == 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
可在此处找到对此主题的进一步参考: