[ECMA-262]-深入探究==运算符的内部执行逻辑
犀牛书3.91节中提到”一个值可以转换为另一个值,并不意味着这两个值是相等的“,比如undefined用在期待布尔值的地方,可以被转换成布尔值false,但undefined !== false。
JavaScript中的==运算符会涉及到一系列的隐式类型转换,有时候运行的结果会让初学者困惑。下面参考ECMA-262对==运算的内部执行逻辑进行分析。
表达式x == y,返回的结果为true或者false。其执行逻辑如下:
- 如果x和y的类型相同,那么执行
x === y - 如果x和y分别为null和undefined,那么返回true。
- 如果x是Number,y是String,那么执行
x == ToNumber(y),并返回结果。 - 如果x是String,y是Number,同上。
- 如果x是Boolean,那么执行
ToNumber(x) == y,并返回结果。 - 如果y是Boolean,同上。
- 如果x是String/Number/Symbol之一,y是Object,那么执行
x == ToPrimitive(y),并返回结果。 - 如果y是String/Number/Symbol之一,x是Object,同上。
- 否则,返回false。
上述的执行逻辑有几点需要着重注意:
- 只要遇到Boolean类型,就直接调用ToNumber转将布尔值为数字类型。
- 上述逻辑中没有涉及到的,都返回false,这其中就包括
null == 0和undefined == 0,这两个表达式的结果都为false,并且任意两个不同的Object类型,都不相等。
接下来看几个例子:
1 | 'abc' ? true : false;//true |
这里顺便提一下逻辑非运算符,看如下的例子:
1 | NaN == false;//false |
NaN和false进行相等比较时,因为false时Boolean类型,需要先转换为Number类型,也就是0,那么NaN和0都是Number类型,很显然两者并不相等。
但是对NaN进行逻辑非操作后,却跟true相等。这是因为在进行逻辑非操作的时候,会调用ToBoolean()函数将右边的变量转换为Boolean类型,NaN转换为Boolean类型之后为false,然后再取非,为ture。