提问
相等运算符(==)是一个让人头痛的运算符,它的语法行为多变,不符合直觉。
请看下面的这个表达式,请问它们的值是多少。
0 == null
false == '0.0'
以及为什么?
破题
数据类型转换表
ECMA规定了 == 运算符具体的处理,我将其内容整理,形成了如下的表格
类型 | boolean | string | number | symbol | object | null | undefined |
---|---|---|---|---|---|---|---|
boolean | === | Number(boolean) == string | Number(boolean) == number | Number(boolean) == symbol | Number(boolean) == object | Number(boolean) == null | Number(boolean) == undefined |
string | Number(boolean) == string | === | Number(string) == number | false | string == toPrimitive(object) | false | false |
number | Number(boolean) == number | number == Number(string) | === | false | number == toPrimitive(object) | false | false |
symbol | symbol == Number(boolean) | false | false | === | symbole == toPrimitive(object) | false | false |
object | object == Number(boolean) | toPrimitive(object) == string | toPrimitive(object) == number | toPrimitive(object) == symbol | === | false | false |
null | Number(boolean) == null | false | false | false | false | === | true |
undefined | Number(boolean) == undefined | false | false | false | false | true | === |
转换表内容解析
以上的表格虽然表达的很清楚,但是我们翻阅的时候,可能会觉得繁琐,所以我们在这里将上面的表格进行一次提炼整理。
我们在分析上面的内容的时候,发现以下规律
- null == undefined 结果为true
- null | undefined 与 其他类型比较均为 false
- string | number | symbol == object 会将使用toPrimitive将object转换为原始类型数据,在进行比较(ps: 稍后会补一篇文章用来解释toPrimitive的行为)
- symbol == string | number 比较均为 false
- boolean == number | string 比较会转为 number
- string == number 比较会转为 number
揭晓答案
现在我们回到前言中提到的问题,通过正文中的学习,我想我们可以快速而且非常自信的回答出答案了。
0 == null // false
false == '0.0' // true
怎么样,小伙伴们是不是都回答正确了呢。
下面让我们来具体的分析下上面两道题。
-
0 == null
考的知识点是 null 与 非 null | undefined 比较返回均为false
-
false == '0.0'
这道题需要进行以下三步,方能得到答案
1:
Number(false) == '0.0'
得到0 == '0.0
2:
0 == Number('0.0')
得到0 == 0.0
3:
0 === 0.0 // true
ECMA算法参考
ReturnIfAbrupt(x).
ReturnIfAbrupt(y).
If Type(x) is the same as Type(y), then
Return the result of performing Strict Equality Comparison x === y.
If x is null and y is undefined, return true.
If x is undefined and y is null, return true.
If Type(x) is Number and Type(y) is String, return the result of the comparison x == ToNumber(y).
If Type(x) is String and Type(y) is Number, return the result of the comparison ToNumber(x) == y.
If Type(x) is Boolean, return the result of the comparison ToNumber(x) == y.
If Type(y) is Boolean, return the result of the comparison x == ToNumber(y).
If Type(x) is either String, Number, or Symbol and Type(y) is Object, then return the result of the
comparison x == ToPrimitive(y).
If Type(x) is Object and Type(y) is either String, Number, or Symbol, then return the result of the comparison ToPrimitive(x) == y.
Return false.