[ECMA-262]-深入探究==运算符的内部执行逻辑

犀牛书3.91节中提到”一个值可以转换为另一个值,并不意味着这两个值是相等的“,比如undefined用在期待布尔值的地方,可以被转换成布尔值false,但undefined !== false

JavaScript中的==运算符会涉及到一系列的隐式类型转换,有时候运行的结果会让初学者困惑。下面参考ECMA-262对==运算的内部执行逻辑进行分析。

表达式x == y,返回的结果为true或者false。其执行逻辑如下:

  1. 如果x和y的类型相同,那么执行x === y
  2. 如果x和y分别为null和undefined,那么返回true。
  3. 如果x是Number,y是String,那么执行x == ToNumber(y),并返回结果。
  4. 如果x是String,y是Number,同上。
  5. 如果x是Boolean,那么执行ToNumber(x) == y,并返回结果。
  6. 如果y是Boolean,同上。
  7. 如果x是String/Number/Symbol之一,y是Object,那么执行x == ToPrimitive(y),并返回结果。
  8. 如果y是String/Number/Symbol之一,x是Object,同上。
  9. 否则,返回false。

上述的执行逻辑有几点需要着重注意:

  1. 只要遇到Boolean类型,就直接调用ToNumber转将布尔值为数字类型。
  2. 上述逻辑中没有涉及到的,都返回false,这其中就包括null == 0undefined == 0,这两个表达式的结果都为false,并且任意两个不同的Object类型,都不相等。

接下来看几个例子:

1
2
3
4
5
6
7
8
'abc' ? true : false;//true

'abc' == true;//false
'1' == true;//true

null == false;//false
undefined == false//false
null == undefined;//true

这里顺便提一下逻辑非运算符,看如下的例子:

1
2
NaN == false;//false
!NaN == true;//true

NaN和false进行相等比较时,因为false时Boolean类型,需要先转换为Number类型,也就是0,那么NaN和0都是Number类型,很显然两者并不相等。

但是对NaN进行逻辑非操作后,却跟true相等。这是因为在进行逻辑非操作的时候,会调用ToBoolean()函数将右边的变量转换为Boolean类型,NaN转换为Boolean类型之后为false,然后再取非,为ture。