为何null>0,null==0为false,而null>=0为true?

开发 前端
javaScript中有很多异于常人思维的逻辑,比如null > 0, null == 0都为false,但null >= 0 却为true。

前言

javaScript中有很多异于常人思维的逻辑,比如null > 0, null == 0都为false,但null >= 0 却为true。

有些人看到这里觉得这怎么可能,于是跑到浏览器控制台尝试执行了一番,执行后的结果,让自己大吃一惊。

图片

心想自己可能因为这个写了不少bug,今天又学到了一个知识点,但这你要不去了解它的执行原理,估计你怎么都想不通。

下面我们就尝试去一探究竟吧!

ToPrimitive 算法

JavaScript 对象转换到基本类型值时,会使用 ToPrimitive 算法,这是一个内部算法,是编程语言在内部执行时遵循的一套规则。

hint

ToPrimitive 算法在执行时,会被传递一个参数 hint,表示这是一个什么类型的运算(也可以叫运算的期望值),根据这个 hint 参数,ToPrimitive 算法来决定内部的执行逻辑。

hint 参数的取值只能是下列 3 者之一:

  • string
  • number
  • default

toPrimitive转换规则

如果传入参数是string,也就是对象到字符串的转换」,经过了如下步骤:

  • 如果对象中有toString()方法,则调用这个方法。如果它返回一个原始值(undefined、Boolean、Number、String、BigInt、Symbol 和 null),js将这个值转换为字符串(如果本身不是字符串的话),并返回这个字符串结果。
  • 如果对象没有toString()方法,或者toString()没有返回一个原始值,那么js会调用valueOf()方法。如果返回值是原始值,js将这个值转换为字符串,并返回字符串结果。
  • 否则,js抛出一个类型错误异常。

「如果传入参数是number/default,也就是对象到数字的转换」,经过了如下步骤:

和上面有点不同,到数字的转换会先尝试使用valueOf()方法

  • 如果对象具有valueOf()方法,后者返回一个原始值,则js会将其转换为数字(如果需要的话)并返回这个数字。
  • 否则,如果对象具有toString()方法,返回一个原始值(字符串直接量),则js将其转换为数字类型,并返回这个数字。
  • 否则,js抛出一个类型错误异常。

抽象关系比较算法

  1. 调用 b 的 ToPrimitive(hit Number) 方法.
  2. 调用 a 的 ToPrimitive(hit Number) 方法.
  3. 如果此时 Result(1) 与 Result(2) 都是字符串,跳到步骤 16.
  4. 调用 ToNumber(Result(1)).
  5. 调用 ToNumber(Result(2)).
  6. 如果 Result(4) 为 NaN, return undefined.
  7. 如果 Result(5) 为 NaN, return undefined.
  8. 如果 Result(4) 和 Result(5) 是相同的数字,return false.
  9. 如果 Result(4) 为 +0, Result(5) 为 -0, return false.
  10. 如果 Result(4) 为 -0, Result(5) 为 +0, return false.
  11. 如果 Result(4) 为 +∞, return false.
  12. 如果 Result(5) 为 +∞, return true.
  13. 如果 Result(5) 为 -∞, return false.
  14. 如果 Result(4) 为 -∞, return true.
  15. 如果 Result(4) 的数值大小小于 Result(5),return true,否则 return false.
  16. 如果 Result(2) 是 Result(1) 的前缀 return false. (比如 "ab" 是 "abc" 的前缀)
  17. 如果 Result(1) 是 Result(2) 的前缀, return true.
  18. 找到一个位置 k,使得 a[k] 与 b[k] 不相等.
  19. 取 m 为 a[k] 字符的数值.
  20. 取 n 为 b[k] 字符的数值.
  21. 如果 m < n, return true,否则 return false.

判断null>0

按照上面这个步骤,我们可以尝试来判断一下null>0的结果

首先第一二步就是为它们分别调用ToPrimitive()将这两个值转换为原始类型,由于这两个值都是基本类型,所以他们转换后还是本身

然后第三步就不适用,我们接着看第四五步,将两个值都转为Number类型,null转换成了+0,而0还是0。

接着看六七,由于两者都不是NaN,所以我们直接看第八步,在js中+0与0是一样的,所以返回false

null > 0 // false
null < 0 // false

抽象相等比较算法

  1. 如果 a 与 b 的类型相同,则:
  • 如果 Type(b) 为 undefined,return true.
  • 如果 Type(b) 为 null,return true.
  • 如果 Type(b) 为 number,则:
  • 如果 b 为 NaN,return false.
  • 如果 a 为 NaN,return false.
  • 如果 a 与 b 数值相同,return true.
  • 如果 a 为 +0,b 为 -0,return true.
  • 如果 a 为 -0,b 为 +0,return true.
  • 否则 return false.
  • 如果 Type(b) 为 string,且 a 与 b 是完全相同的字符串,return true,否则 return false.
  • 如果 Type(b) 是 boolean,如果都是 true 或 false,return true,否则 return false.
  • 如果 a 与 b 是同一个对象引用,return true,否则 return false.
  1. 如果 a 为 null,b 为 undefined,return true.
  2. 如果 a 为 undefined,b 为 null,return true.
  3. 如果 Type(a) 为 number,Type(b) 为 string,返回 a == ToNumber(b) 的结果.
  4. 如果 Type(a) 为 string,Type(b) 为 number,返回 ToNumber(a) == b 的结果.
  5. 如果 Type(a) 为 boolean,返回 ToNumber(a) == b 的结果.
  6. 如果 Type(b) 为 boolean,返回 a == ToNumber(b) 的结果.
  7. 如果 Type(a) 是 string 或 number,且 Type(b) 是对象类型,返回 a == ToPrimitive(b) 的结果.
  8. 如果 Type(a) 是对象类型,且 Type(b) 是 string 或 number,返回 ToPrimitive(a) == b 的结果.
  9. 否则 return false.

判断null==0

null == 0 // false

null == 0 走到了第 10 步,返回了默认的 false。

大于等于操作符>=

从常理上来讲,如果null>0为false,null==0也为false,那么null>=0肯定也为false。但事实并非如此

javascript 是这么定义大于等于判断的:

如果 a < b 为 false,则 a >= b 为 true

这个规则是不是有点逆于常人思维,但它却又是合理的,当a<b为false,那反过来a>=b肯定就为true对吧

所以null>=0为true,是因为null<0为false,看到这里,是不是又恍然大悟了呢?


责任编辑:华轩 来源: 前端南玖
相关推荐

2023-12-20 08:22:29

JavaIntegertrue

2015-11-23 10:09:30

Java

2020-12-31 08:05:27

MySQL服务器版本号

2017-09-05 09:02:06

Oraclenot null优化

2024-04-25 08:21:36

Java对象计数法

2016-12-22 18:38:49

JavaAndroid

2024-09-12 08:45:23

2015-03-13 09:36:09

NULLnullptr

2017-03-27 16:44:07

戴尔服务器

2021-04-26 14:00:43

Java 数据类型

2021-08-18 08:20:14

SQL除数统计

2019-11-07 16:51:15

NULL三值逻辑SQL

2010-09-17 10:24:47

SQL中IS NULL

2022-06-13 13:17:00

流计算数据

2020-05-18 14:40:19

Javanull对象

2021-07-17 06:41:12

谷歌Chrome浏览器

2012-03-01 12:50:03

Java

2022-07-22 09:15:07

OpitonalJava代码

2010-09-28 11:48:36

SQL NULL值

2023-09-14 12:03:30

空指针判空
点赞
收藏

51CTO技术栈公众号