分析 [] == 0,[] == [], ![] == [],{} == {}, !{} = {}
== 根 === 区别是判断数据类型
两边是相同类型会直接比较,如果是不同的数据类型,是需要先做数据类型转换,然后再进行比较的。
为何 {} == {}, [] == [] 均为false
因为两边数据类型相同均为引用类型,引用类型会比较地址,所以均为false
先看看相等操作符==
的一些转换规则:
- 如果有一个操作数是布尔值,则会先隐式调用
window
对象上的Number
转型函数,将其转换为数值,false
转为0
,true
转为1
,再进行判断。 - 如果有一个操作数是字符串,另一个是数值,则隐式调用
Number
转型函数,将字符串转换为数值,再进行判断。 - 如果有一个操作数是对象,则调用对象的
valueOf
方法,如果返回的是复杂数据类型,则在返回值得基础上再调用toString
方法,最后根据以上规则进行比较。
为何[] == ![],因为!运算优先级高于 ==,所以先运算![]再比较大小
1.隐式调用Boolean
转型函数,对空数组转换成Boolean
值,再对结果取反。此时比较 [] == false
2.隐式调用Number转型函数,对false转换成number值,此时比较 [] == 0
3.隐式调用toString转型函数,对空数组转换成string值,此时比较 “” == 0
4.隐式调用Number转型函数,对空字符串转换成number值,此时比较 0 == 0 得到结果 true
转换布尔值规则
非0数字,非空字符串 转换为true
undefined 转换为false
null 转换为 false
0,'' 转换为false
引用类型转换字符串调用toString
[].toString = ''
{}.toString = '[object Object]'
为何{} == !{}结果为false,分析可得:
1. 隐式调用Boolean
转型函数,对空数组转换成Boolean
值,再对结果取反。此时比较 {} == false
2.隐式调用Number转型函数,对false转换成number值,此时比较 {} == 0
3. 隐式调用toString转型函数,对空数组转换成string值,此时比较 '[object Object]' ==0
4. 隐式调用Number转型函数,对字符串转换成number值,此时比较 NaN== 0, 返回false