JavaScript中null == 0 为false , null >= 0 为 true

一、前言

        先说答案:

null == 0 // false
null > 0 // false
null >= 0 //true
null <= 0 //true

   很多人认为 null 应该转化成 0 ,然后 0 === 0 为true。其实这是对操作符在转换操作数类型时的规则不熟悉导致的。

        实际上,在javascript不同操作符的类型的转化规则是不同的且相互独立。并且一些操作符对特定的类型制定了特殊的规则。

二、为什么

 1.null == 0 为false

  • 先看一下在 '==' 操作符下的比较规则

《JavaScript高级程序设计(第4版)》中第3章的 3.5.8 相等操作符中指出:

在转换操作数的类型时,相等和不相等操作符遵循如下规则

         如果任一操作数是布尔值,则将其转换为数值再比较是否相等。 false 转换为 0 true 转换为 1
         如果一个操作数是字符串,另一个操作数是数值,则尝试将字符串转换为数值,再比较是否相等。
         如果一个操作数是对象,另一个操作数不是,则调用对象的 valueOf() 方法取得其原始值,再 根据前面的规则进行比较。
在进行比较时,这两个操作符会遵循如下规则。
         null undefined 相等。
         null 和 undefined 不能转换为其他类型的值再进行比较。
         如果有任一操作数是 NaN ,则相等操作符返回 false ,不相等操作符返回 true 。记住:即使两 个操作数都是 NaN ,相等操作符也返回 false ,因为按照规则, NaN 不等于 NaN
         如果两个操作数都是对象,则比较它们是不是同一个对象。如果两个操作数都指向同一个对象,
则相等操作符返回 true 。否则,两者不相等。

通过上面规则我们可以看到对null 和undefined制定了特殊的规则,即 null 和 undefined 不能转换为其他类型的值再进行比较。所以在null == 0 的判断中,不能将null 转化为0比较,同时也没有其他规则可以遵循,所以最后会返回 false。

同样的,根据规则 undefined == 0 也返回 false。

 2.null >= 0 为true

  • 在看看关系操作符(包括小于(<)、大于(>)、小于等于(<=)和大于等于(>=))的规则
《JavaScript高级程序设计(第4版)》中第3章的 3.5.7 关系操作符中指出:
ECMAScript 中的其他操作符一样,在将它们应用到不同数据类型时也会发生类型转换和其他行为。
如果操作数都是数值,则执行数值比较。
如果操作数都是字符串,则逐个比较字符串中对应字符的编码。
 如果有任一操作数是数值,则将另一个操作数转换为数值,执行数值比较。
如果有任一操作数是对象,则调用其 valueOf() 方法,取得结果后再根据前面的规则执行比较。
如果没有 valueOf() 操作符,则调用 toString() 方法,取得结果后再根据前面的规则执行比较。
如果有任一操作数是布尔值,则将其转换为数值再执行比较。

可以看到,在关系操作符中有 如果有任一操作数是数值,则将另一个操作数转换为数值,执行数值比较。这一条规则,因此在 null >= 0 时,由于有 '0' 这个操作数为数值,另一个操作数会进行转换,将null 转化为 0 然后 0 === 0 ,返回 true。

同理:

null > 0 //false

null <= 0 //true

三、算法细节

        其实看过上面的规则后,已经可以判断出正确答案了,但是这些规则都是一些具体算法的描述总结,而底层实现源码也不是容易看懂的。恰好在知乎上看到一个回答,给出了一个判断的过程,也可以让我们感受一下底层是如何判断的:

Return If Abrupt(x).
Return If Abrupt(y).
If Type(x) is the same as Type(y), then
Return the result of performing Strict Equality Comparisonx === y.
If x is null and y is undefined, return true.
If x is undefined and y is null, return true.
If Type(x) is Number and Type(y) is String,
return the result of the comparison x == ToNumber(y).
If Type(x) is String and Type(y) is Number,
return the result of the comparison ToNumber(x) == y.
If Type(x) is Boolean, return the result of the comparisonToNumber(x) == y.
If Type(y) is Boolean, return the result of the comparison x == ToNumber(y).
If Type(x) is either String, Number, or Symbol and Type(y)is Object, then
return the result of the comparison x == ToPrimitive(y).
If Type(x) is Object and Type(y) is either String, Number, or Symbol, then
return the result of the comparison ToPrimitive(x) == y.
Return false.
​

即下方的步骤:

  • 如果x不是正常值(比如抛出一个错误),中断执行。
  • 如果y不是正常值,中断执行。
  • 如果Type(x)与Type(y)相同,执行严格相等运算x === y。
  • 如果x是null,y是undefined,返回true。
  • 如果x是undefined,y是null,返回true。
  • 如果Type(x)是数值,Type(y)是字符串,返回x == ToNumber(y)的结果。
  • 如果Type(x)是字符串,Type(y)是数值,返回ToNumber(x) == y的结果。
  • 如果Type(x)是布尔值,返回ToNumber(x) == y的结果。
  • 如果Type(y)是布尔值,返回x == ToNumber(y)的结果。
  • 如果Type(x)是字符串或数值或Symbol值,Type(y)是对象,返回x == ToPrimitive(y)的结果。
  • 如果Type(x)是对象,Type(y)是字符串或数值或Symbol值,返回ToPrimitive(x) == y的结果。
  • 返回false。

作者:老猫爱打盹
链接:https://www.zhihu.com/question/52666420/answer/132231109

四、'==' 的一些特殊情况及比较的结果

表 达 式
          结果             
null == undefined
true
"NaN" == NaN
false
5 == NaN
false
NaN == NaN
false
NaN != NaN
true
false == 0
true
true == 1
true
true == 2
false
undefined == 0
false
null == 0
false
"5" == 5
true

五、参考资料

[美]马特·弗里斯比(Matt Frisbie)著 李松峰 译 ——《JavaScript高级程序设计(第4版)》

  • 4
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值