[ECMA-262]-深入探究关系比较运算符的内部执行逻辑

文章开始之前,先来看个例子:

1
2
3
4
5
6
7
8
9
null == 0;//false
null > 0;//false
null < 0;//false
null >= 0;//true

undefined == 0;//false
undefined > 0;//false
undefined < 0;//false
undefined >=0;//false

之前的文章中深入解析过==运算符的执行逻辑,null == 0的结果为false是没有什么疑问的,但是后面的两行代码的结果就又让人困惑了。

接下来,就以x < y为例,参考ECMA-262来对关系比较运算符的执行逻辑进行分析:

  1. 执行px = ToPrimitive(x,hint Number); py = ToPrimitive(y,hint Number);
  2. 如果px和py的类型都是String,那么
    • 如果py是px的前缀,那么返回false。
    • 如果px是py的前缀,那么返回true。
    • 如果px和py在第k个位置的字符开始不一样(k之前的字符都完全一样),令m是px中第k个位置的字符的编码值,n是py中第k个位置的字符的编码值,如果m<n,返回true,否则,返回false。
  3. 其他情况
    • 执行nx = ToNumber(px);ny = ToNumber(py);
    • 如果nx或者ny是NaN,返回undefined。
    • 如果nx和ny是相同的数值,返回false。
    • 如果nx是+0,ny是-0,返回false。
    • 如果nx是-0,ny是+0,返回false。
    • 如果nx是+∞,返回false。
    • 如果ny是+∞,返回true。
    • 如果ny是-∞,返回false。
    • 如果nx是-∞,返回true。
    • 如果nx数学意义上的值小于ny,并且都是有穷的数并且不为0,返回true,否则,返回false。

x >= y的执行逻辑就非常简单了,

  1. 如果x < y的结果是true或者undefined,那么返回false。
  2. 如果x < y的结果是false,那么返回true。

我们再来文章开头的例子:

按照上述执行逻辑,null < 0null > 0的结果都为false,null >= 0null <= 0的结果都为true。

undefined就比较特殊了,undefined转换为数字之后是NaN,根据上述逻辑,undefined与0进行<>运算的时候,返回的结果是undefined(这一点是一个疑问点,在浏览器端输出的结果是false,可能是自动将undefined转换为布尔值了?),所以<=>=运算的结果为都为false。