看看你忽视了多少js等性运算符的规则

作者:杨润炜
日期:2016/8/9 14:22

我们在写js时,当需要比较两个变量的大小时,会用到等性运算符,它们分别是’==’,’===’,’!=’和’!==’。我们都知道’==’和’!=’都对变量进行类型转换后再比较。然后除了这点,等性运算符的规则就这么简单么?直到看到下面的程序结果,你就不会这么认为了。

  1. 0 <= null; // true
  2. 0 == null; // false
  3. 0 === null; // false
  4. 0 < null; // false

第一次看到这样的逻辑,不禁会想:“这。。。js逆天了,这么坑的逻辑,以后都不敢写js了!”。然而,这看起来虽然不符合我们平时的思维逻辑,但一定是符合js规则的,因为这是根据js的规则出来的结果。那怎样用规则解释这个奇特的现象呢?
ecmascript关于等性运算符规则如下:

执行类型转换的规则如下:
如果一个运算数是 Boolean 值,在检查相等性之前,把它转换成数字值。false 转换成 0,true 为 1。
如果一个运算数是字符串,另一个是数字,在检查相等性之前,要尝试把字符串转换成数字。
如果一个运算数是对象,另一个是字符串,在检查相等性之前,要尝试把对象转换成字符串。
如果一个运算数是对象,另一个是数字,在检查相等性之前,要尝试把对象转换成数字。
在比较时,该运算符还遵守下列规则:
值 null 和 undefined 相等。
在检查相等性时,不能把 null 和 undefined 转换成其他值。
如果某个运算数是 NaN,等号将返回 false,非等号将返回 true。
如果两个运算数都是对象,那么比较的是它们的引用值。如果两个运算数指向同一对象,那么等号返回 true,否则两个运算数不等。
重要提示:即使两个数都是 NaN,等号仍然返回 false,因为根据规则,NaN 不等于 NaN。

从上述规则我们可以知道,等性运算符是不会对null和undefined进行类型转换的,
注:这里我们需要知道null转换为数值类型时,值为0。即:

  1. Number(null); // 0
  2. 0 < null; // false

所以才会有:

  1. 0 == null; // false
  2. 0 === null; // false

而’<=’比较是会对变量进行类型转换,所以:

  1. 0 <= null; // true

所以,这便是出现上述现象的原因了。
关于规则,还有以下两点需要注意:

1.关于对象间的相等,比较的是它们的引用值。这有点像c中的指针的比较。下面来看看示例:
  1. var a = {}, b = {}, c = a;
  2. a == b; // false
  3. a === b; // false
  4. a == c; // true
  5. a === c; // true

a和b的引用值看起来虽然一样,但在内存里是两个对象,即地址不一样了。而c与a便引用了同一个对象,这样它俩就相等了。
如果只是想比较对象的值,可以将对象序列化后再比较。如下所示:

  1. JSON.stringify(a) == JSON.stringify(b); // true
  2. JSON.stringify(a) === JSON.stringify(b); // true
2.NaN不等于任何值,包括它自己

NaN是个奇葩,与任何人关系都差,包括对自己也是,哈哈。所以:

  1. NaN == NaN; // false
  2. NaN === NaN; // false

然而,如果谁都与它不相等,那么怎样判别它呢?这就需要交给伟大的’isNaN()’了,它的出现,只为证明’NaN’的存在。

  1. isNaN(NaN); // true
  2. isNaN(100); // false

参考

ECMAScript 等性运算符

感谢您的阅读!
如果看完后有任何疑问,欢迎拍砖。
欢迎转载,转载请注明出处:http://www.yangrunwei.com/a/67.html
邮箱:glowrypauky@gmail.com
QQ: 892413924