JavaScript 比较运算

本文详细解析了JavaScript中抽象比较运算符(==和!=)的行为,包括类型转换规则及常见误区,并介绍了如何避免由类型转换引起的错误。同时,文中还讨论了NaN的特性及其与其他值的比较方式。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

抽象比较运算符 和 类型转换

问题

如果计算对象的类型不匹配,抽象比较运算符(== 和 !=)将转换其运算对象。这种强制转换是大多数计算结果的困惑问题的根源,通常,这些运算符并不总是像我们期待的那样转换类型:

"" ==  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” 是不同的值,所以结果是 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

全局对象的 NaN 属性

NaN(Not a Number)是一个特殊值,用于期待是数值而非数值时(1 * “two”),或者当计算值无效时(Math.sqrt(-1))。

任何比较运算或关系运算 与 NaN 比较 都返回 false,甚至NaN 与自己比较。因为 NaN是一个无意义的值。

(1 * "two") === NaN  //false

NaN === 0;          // false
NaN === NaN;        // false
Number.NaN === NaN; // false

NaN < 0;            // false
NaN > 0;            // false
NaN > 0;            // false
NaN >= NaN;         // false
NaN >= 'two';       // false

非等运算永远返回true:

NaN !== 0;          // true
NaN !== NaN;        // true

检查值是否是NaN:

Number.isNaN(NaN);         // true
Number.isNaN(0 / 0);       // true
Number.isNaN('str' - 12);  // true

Number.isNaN(24);          // false
Number.isNaN('24');        // false
Number.isNaN(1 / 0);       // false
Number.isNaN(Infinity);    // false

Number.isNaN('str');       // false
Number.isNaN(undefined);   // false
Number.isNaN({});          // false

根据协议,全局函数 isNaN() 返回 true,不仅用于 NaN,还可以是任何不能转换成数字的值或表达式:

isNaN(NaN);         // true
isNaN(0 / 0);       // true
isNaN('str' - 12);  // true

isNaN(24);          // false
isNaN('24');        // false
isNaN(Infinity);    // false

isNaN('str');       // true
isNaN(undefined);   // true
isNaN({});          // true

ECMAScript 6定义了一个 “相同” 算法,叫做 SameValue,可以用Object.is 调用。不像 == 和 ===,Object.is() 把NaN 对待成与 NaN 相同。但是 -0 不等于 +0:

Object.is(NaN, NaN)      // true
Object.is(+0, 0)         // false

NaN === NaN              // false
+0 === 0                 // true

但是,NaN是一个数字值,意味着它不等于字符串的 “NaN”:

typeof(NaN) === "number"; //true
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值