很多人包括我在内很抵触这种问题?,因为很长一段时间我一直弄不明白 == 和 === 到底是怎么个规则。如果你也没闹明白 == 和 ===,读了这篇文章应该至少不会见到这俩操作符就觉得恶心了吧?。
另外需要注意的是,== 的英文名叫 Abstract Equality Comparison;=== 则是 Strict Equality Comparison。
废话不多说,我们开始搞起
首先需要注意的是
2 == 3
最后会返回 2 === 3
的执行结果2 == '3'
就会变成 2 == 3
最后会比较 2 === 3
这就是最基本的规则
然后我们再来看看具体的转换规则⬇️:
===
操作符undefined
和 null
比较string
和 number
boolean
object
举几个?:
20190310173625.png
这么看来转换规则是不是很清晰明了?
附上一张转换规则图,忘记了就看看,当然正常情况下应该用 === 代替 == 避免不必要的麻烦:
20190311001056.png
ecma 的规范:http://www.ecma-international.org/ecma-262/6.0/#sec-abstract-equality-comparison
上述在比较的过程中,涉及到类型的转换,如字符串转整数、布尔值转整数、以及获取对象原始值等等。了解一下这些不同类型之间是如何转换的:
接着我们再来研究一下对象怎么转换为原始值的:
我们需要知道转换类型的这个方法在 JS 源代码中是
ToPrimitive
这个方法,该方法有一个可选参数PreferredType
,这个参数的作用是指定期望类型;如果第一个参数对应的对象可以被转换为不止一种类型,那么后者可以作为一种暗示,表示该对象应该转换为那种类型
number
)valueOf
方法:toString
方法:string
:toString
方法:valueOf
方法:string
):toString
方法:valueOf
方法:简单的说就是默认调用 valueOf
方法,然后是 toString
方法;如果对象是 Date
类型或对象的期望类型为 string
,那么先调用 toString
方法?
举几个???吧:
20190310181039.png
普通的对象,首先调用 valueOf 方法,返回的结果并非原始值,那么会调用 toString 方法
20190310181441.png
假设我们重写 valueOf 方法,valueOf 和 toString 同时返回 string 原始值。使用 == 操作符可以看出,对象还是优先使用了 valueOf 方法返回的值
20190310181837.png
上面的数组同理,首先默认调用 valueOf 方法,如不是原始值,则调用 toString 方法
20190310182219.png
这个包括众多类型的项的数组也是一样?
20190310182751.png
再看看 Date 类型,他的期望类型是 string 因此首先调用的是 toString 方法,该方法返回一个原始值,那么就是用这个原始值
下面我们来看看转换成 number 类型的规则:
undefined
? NaN
如果是 undefined 则直接转换成 NaNnull
? 0
如果是 null 则转换成 0boolean
? 0/1
如果是 boolean 则转换成 0 或 1string
? 0/NaN/(parse to number)
如果是 string 则转换成对应的 number,空字符串转换为 0,无法转换的则为 NaNobject
? 首先获取原始值然后再转为 number看几个?:
20190310233718.png
转为 string 的规则为:
undefined
? 'undefined'
null
? 'null'
number
? 'number
boolean
? 'true'/'false'
object
? 首先获取原始值,然后转为 string20190310234912.png
常见的问题:哪些是 falsy 哪些是 truthy:
❌下面这些在 JS 中都为 falsy 除此之外的都是 truthy
undefined
? falsynull
? falsy0
? falsy""
? falsyNaN
? falsy因此转换规则如下:
undefined
? false
null
? false
number
? 当为 0 时 false
否则为 true
string
? 当为空字符串时为 false
否则为 true
object
? true
array
? true
Date
? true
??是几个例子:
20190311000041.png
附上一张不同类型间转换规则:
20190311001627.png
就写到这里,基本上 == 和类型转换就是这个样子❕
EOF
参考: