在javascript中,null>=0 为真,null==0却为假,null的值详解

前端之家收集整理的这篇文章主要介绍了在javascript中,null>=0 为真,null==0却为假,null的值详解前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。

在javascript中,null>=0 为真,null==0却为假,null的值详解

1.前言

今天看见朋友们在讨论一个问题,说 null 到底和 0 是不是相等的。

听到这里,自己赶紧去写个 Demo 试一下。

404_10@ <Meta charset="UTF-8"> MR_LP:3206064928

什么情况?

为什么 console.log(null <= 0); 和 console.log(null >= 0); 这两条的判断是 true 呢?

2.查阅资料

如果想明确,这个问题具体是怎么回事,那么我们需要重新来回顾一下我们的 ECMAScript Language Specification (HTML version),翻译过来就是ECMAScript语言规范(HTML版本)。

2.1 内部相等性运算算法

首先我们来看一下 ES3 关于 内部相等性运算的算法实现。

2.2 内部关系运算算法

接下来我们再来看一下 ES3 关于 内部关系运算的算法实现。

2.3 ES3 的 运算符

2.3.1 ES3 的 “>” 运算符:

) The production RelationalExpression : RelationalExpression > ShiftExpression is evaluated as follows: 1. Evaluate RelationalExpression. 2. Call GetValue(Result(1)). 3. Evaluate ShiftExpression. 4. Call GetValue(Result(3)). 5. Perform the comparison Result(4) < Result(2). 6. If Result(5) is undefined,return false. Otherwise,return Result(5).

2.3.2 ES3 的”>=” 运算符:

= ) The production RelationalExpression : RelationalExpression >= ShiftExpression is evaluated as follows: 1. Evaluate RelationalExpression. 2. Call GetValue(Result(1)). 3. Evaluate ShiftExpression. 4. Call GetValue(Result(3)). 5. Perform the comparison Result(2) < Result(4). (see 11.8.5). 6. If Result(5) is true or undefined,return true.

2.3.3 ES3 的 “==” 运算符 :

3. 根据资料得出的内容

着重看一下,上面特意加粗的地方,我们可以明确下面三件事。

  1. 关系运算符 和 相等运算符 并不是一个类别的.
  2. 关系运算符,在设计上,总是需要运算元尝试转为一个number . 而相等运算符在设计上,则没有这方面的考虑.
  3. 最重要的一点,不要把 拿 a > b,a == b 的结果 想当然的去和 a >= b 建立联系. 正确的符合最初设计思想的关系是 a > b 与 a >= b是一组 . a == b 和其他相等运算符才是一组. 比如 a === b,a != b,a !== b .

那么我们就可以反过来看这个问题了。

0 // null 尝试转型为number,则为0 . 所以结果为 false,null >= 0 // null 尝试转为number,则为0,结果为 true. null == 0 // null在设计上,在此处不尝试转型. 所以 结果为false.

这里引用一下 Franky大大的话。

a >= b 运算符只是简单的去对 a < b的结果取反. 我以为这是一个设计上的失误的另一个理由是 undefined,在标准中,被单拎出来.细心的你,也一定发现了这一点. 对于undefined的设计,undefined > 0,undefined < 0,undefined == 0 的结果是符合设计上,逻辑的一致性的. 而null是被遗漏的东西.直到今天早上.我重新翻阅了ES3,5.相关章节. 才恍然大悟自己没有从根本上理解到这个问题.

虽然前面的例子,我catch到了BE当初的设计思想. 但是从全局的角度来看. 从关系运算符到相等运算符,尤其是相等运算符的设计上. 真的十分混乱不堪. BE在信中提到,他对 == 的现状也很无奈. 甚至用愚蠢这个词来形容自己当初的实现(当然他还提到,当初只是为了在10天内设计出js,并跑过qa的测试用例). 即使如此,但是他仍然表示 null == 0 这个结果是他想要的.     

好吧,到了这里,我也有种无力感. 我认为纵观JavaScript,对关系运算和相等运算的设计.除了混乱,我想不出还有什么词来形容它们更恰当. 这一点从,我们生产环境代码中,大量的类型检查,和防御性代码的的存在,就可以证明这一点.

同时 Franky大大还举了另外一个例子。

function case2(a){
if(a == undefined){
...
}
}

// 上面两组完全等价,这就是一种不明确表述.
// 我们永远不知道代码编写者的目的到底是同时匹配null 和 undefined还是只匹配其中某一个

function case3(a){
if(a === null || a === undefined){
...
}
}

// case3 才是最好的表述. 我们明确知道代码编写者的意图.
// 即使很多人可能认为这个代码很愚蠢. 但我坚定的认为这才是好代码.

最后,不得不提到,我发出null >= 0 这封信后,Andrea Giammarchi 表示了对我之前看法的支持,他同我最初的看法一样,认为 null >= 0 的结果应该为 false . 并建议在 ES7 中的严格模式中,修改这个结果. 虽然同样遭到 David Bruant 的反对. 好吧为他和我的这个错误看法,默哀一分钟…

4.后记

所以写代码,写规范,都应该明确表述. 即使表述的很罗嗦,但不会引起歧义或怀疑. 这才是一份好的标准.文档,代码. 而避免歧义,和各种混乱不堪的规则,是一门语言最应遵守的设计原则.

最后也希望大家在日常的开发中,能够少遇坑。

猜你在找的JavaScript相关文章