宽松相等(==)和严格相等(===)的区别在于宽松相等会在比较中进行隐式转换。
1、转Boolean
Boolean(null) // false
Boolean(undefined) // false
Boolean('') // flase
Boolean(NaN) // flase
Boolean(0) // flase
Boolean([]) // true
Boolean({}) // true
Boolean(Infinity) // true
1、undefined \ null \ 数值0 \ NaN \ 空字符串(没长度的)=》假
2、空的引用类型(空数组、空对象)=》真 (猜测是有地址,转换为真)
3、字符串有长度的为真
2、转Number
Number(null) // 0
Number(undefined) // NaN
Number('10') // 10
Number('10a') // NaN
Number('') // 0
Number(true) // 1
Number(false) // 0
Number([]) // 0
Number(['1']) // 1
Number({}) // NaN
字符串内容为数字可以转数值,不为数字转换为NaN
3、转String
String(null) // 'null'
String(undefined) // 'undefined'
String(true) // 'true'
String(10) // '10'
String(1e21) // '1e+21'
String([1,2,3]) // '1,2,3'
String([]) // ''
String([null]) // ''
String([1, undefined, 3]) // '1,,3'
String({}) // '[object Object]'
4、ToPrimitive
ToPrimitive指对象类型类型(如:对象、数组)转换为原始类型的操作。
先调用valueOf,如果不是原始值则接着调用toString
如果两者都没有返回原始值,抛出异常
Number([]) // 0
Number(['10']) //10
-
Number([]), 空数组会先调用valueOf,但返回的是数组本身,不是原始类型,所以会继续调用toString,得到空字符串,相当于Number(''),所以转换后的结果为"0"
隐式转换原则
1、Boolean类型和其他类型比较
-
只要
布尔类型参与比较,该布尔类型的值首先会被转换为数字类型 -
false == 0 // true true == 1 // true true == 2 // false
2、Number类型和String类型的相等比较
当数字类型和字符串类型做相等比较时,字符串类型会被转换为数字类型
0 == '' // true
1 == '1' // true
1e21 == '1e21' // true
Infinity == 'Infinity' // true
true == '1' // true
false == '0' // true
false == '' // true
3、对象类型和原始类型的相等比较
-
当
对象类型和原始类型做相等比较时,对象类型会依照ToPrimitive规则转换为原始类型 -
'[object Object]' == {} // true '1,2,3' == [1, 2, 3] // true [2] == 2 // true [null] == 0 // true [undefined] == 0 // true [] == 0 // true 相当于: '' == 0 // true '' == 0 // true '' == 0 // true
4、null、undefined和其他类型的比较
null和undefined宽松相等的结果为true
null`和`undefined`之间互相`宽松相等(==)`,并且也与其自身相等,但和其他所有的值都不宽松相等(==)
练习
1、[] == ![] // true
js只定义了5种假值 1:undefined 2:null 3:false 4:+0 -0 NaN 5:''(空字符串)
!优先级高,![]->false, [] == false, []->'', '' == false false->0, '' == 0
2、[] == [] // false {} == {} // false
因为[] 或者 {} 都是独立对象,他们在内存中有自己独立的存储区域,直接比较必然为false。
3、[] == 0 // true
[]->'', '' == 0
4、[2] == 2 // true
5、['0'] == false // true
false->0, ['0']->'0', '0' == 0
6、'0' == false // true
false->0, '0'->0, 0 == 0为true
7、[] == false // true
[]->'', '' == false为true
8、[null] == 0 // true
[null]->'', '' == 0为true
9、null == 0 // false
null和其他所有的值都不宽松相等
10、[null] == false // true
[null]->'', '' == false为true
11、null == false // false
12、[undefined] == false // true
[undefined]->'', '' == false为true
13、undefined == false // false
undefined和其他所有的值都不宽松相等