[] == ![],走进==隐式转换的世界
先来公布答案:console.log([] == ![]) // true
,是不是很酷。==
还有个好兄弟——===
,下面就来看看哥俩到底干了啥...
== 的运行机制
==运算符为确定两个运算数是否相等,会对左右两边运算数进行类型转换。
执行类型转换的规则
- 如果一个运算数是Boolean值,在检查相等性之前,把它转化成数字值。false转化成0,true转换为1。
- 如果一个运算数是字符串,另一个是数字,在检查相等性之前,要尝试把字符串转换成数字。
- 如果一个运算数是对象,另一个是字符串,在检查相等性之前,要尝试把对象转换成字符串。
- 如果一个运算数是对象,另一个是数字,在检查相等性之前,要尝试把对象转换成数字。
遵守规则
- 值
null
和undefined
相等。 - 在检查相等性时,不能把
null
和undefined
转换成其他值。 - 如果某个运算数是
NaN
,等号将返回false
,非等号将返回true
。 - 如果两个运算都是对象,那么比较它们的引用值。如果两个运算数指向同一个对象,那么符号返回
true
,否则两个运算数不等。
=== 的运行机制
- 如果类型不同,就[不相等]
- 如果两个都是数值,并且是同一个值,那么[相等];例外的是,如果其中至少一个是NaN,那么[不相等]。(判断一个值是否是
NaN
,只能用isNaN()
来判断) - 如果两个都是字符串,每个位置的字符都一样,那么[相等];否则[不相等]。
- 如果两个值都是
true
,或者都是false
,那么[相等]。 - 如果两个值都引用同一个对象或函数,那么[相等];否则[不相等]。
- 如果两个值都是
null
,或者都是undefined
,那么[相等]。
回头来验证一下[] == ![]
。
第一步:根据运算符的优先级,!
先执行,[]
是一个对象,所以![]
转化为false
第二步:根据类型转换规则第一条——"如果一个运算数是Boolean值,在检查相等性之前,把它转化成数字值。false转化成0,true转换为1。"。所以false
转换成0
(==
右边得到0
)
第三步:根据类型转换规则第三条——"如果一个运算数是对象,另一个是字符串,在检查相等性之前,要尝试把对象转换成字符串。"。左边的[]
调用toString()
,转换成空字符串''
第四步:根据类型转换规则第二条——"如果一个运算数是字符串,另一个是数字,在检查相等性之前,要尝试把字符串转换成数字。"。''
转化成0
。(左边得到0
)
第五步:比较两边大小0==0
,因此结果为true
总结
转化规则那么多,鬼能记得住啊,总结一下,分两类去记就好:
- 原始类型(undefined、null、number、boolean、string)的比较。转成数字的优先级最高,也就是说一方出现数字,另一方也要转成数字比较。
- 原始类型和对象(引用)类型的比较。如果一个是对象,另一个是数值或字符串,把对象转换成基础(原始)类型的值再比较。对象转换成基础类型,利用它的object.toString()或者object.valueOf()方法。
补充一点:虽然==
和===
是比较运算符,但它只是结果返回Boolean值,转化到最后比较的一定不是俩个Boolean值。
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步