概念:无需程序员手动转化,由编译器自动转换的方式称为隐式转换
规则:
1.转化成String : + (字符串链接发)
2.转换为Number类型:
(1) ++/-- (自增自减运算符)
(2)+ - * / % (算数运算符)
(3)> < >= <= == != === !== (关系运算符)
3.转化为Boolean类型: !(逻辑非运算符)
例子总结:
1. 字符串连接符与算术运算符的区分
1+‘true’ ----> String(1) + 'true' ----> '1true'
1+true -----> 1+Number(true) -----> 1+1 ----> 2
1+undefined ----> 1+Number(undefined ) ----> 1+NaN -----> NaN
1+null ---> 1+Number(null) ----> 1+0 -----> 1
2. 关系运算符:
A: 一边是字符串,会将其数据数据类型转化为number之后再做比较
‘2’ > 10 ----> Number('2') > 10 ----> 2> 10 -----> false
B:两边都是字符串,会根据字符串对应的unicode编码转化为数字,利用charCodeAt转化对应的编码
‘2’ > '10' -----> '2'.charCodeAt() > '10'.charCodeAt() -----> 50 > 49 -----> true
C: 多个字符按照从左向右的规则比较
‘abc' > 'b' -----> 'a'.charCodeAt() > 'b'.charCodeAt() -----> 97 > 98 -----> false
'abc' > 'aad' ----> 'a'.charCodeAt() > 'a'.charCodeAt(),相等,继续比较 ----> 'b'.charCodeAt() > 'a'.charCodeAt() ----> 98 > 97 ----> true
D: 无规则模式:
(1) undefine和null:既相等又自等
undefined == undefined ----> true
undefined == null ----> true
null == null ----> true
(2) NaN与任何数据比较都是NaN,包括自身
NaN == NaN ----> false
3.复杂数据类型的转换。valueOf() ---> String() ----> Number()
[1,2] == '1,2' ----> [1,2].valueOf() = [1,2] -----> [1,2].toString() ='1,2' ----->' 1,2' == '1,2' -----> true
面试题:
var a = {
i: 0,
valueOf: function() {
return ++a.i
}
}
if (a ==1 && a == 2 && a==3) {
conosle.log('1')
}
4. 逻辑非隐式转换与关系运算符隐式转换搞混淆
注意点:
(1) 空数组的toString()方法会得到空字符串,空对象的toString()方法会得到字符串[object Object]
(2) 关系运算符将其他数据类型通过Number()转化为数字,逻辑非运算符将其他数据类型通过Boolean()转化为布尔类型
(3) 0,-0,NaN,undefined,null,' ',false,document.all() -----> 这8个转化为布尔类型为false,其他都为true
(4) 值类型赋值时,拷贝的是数据;引用类型拷贝时,拷贝的是地址
(5) 声明变量开辟的内存空间通常是栈内存,而值类型数据存储在栈中,引用类型数据存储在堆中,变量中存储的是堆地址
[] == 0 ----> [].valueOf().toString() = '0' ---> Number('0') = 0 -----> true
![] == 0 ----> 逻辑非的优先级高于关系运算符---> Boolean([]) = true ---> ![] = false ----> false == 0 ----> true
![] == [] ----> 逻辑非的优先级高于关系运算符---> !Boolean([]) == [].valueOf().toString() -----> false == ' ' ------> Number(false ) == Number( ' ' ) ---> 0 ==0 -----> true
[] == [] -----> false ----> 引用类型数据存在堆中,栈中存储的是地址,所以比较的结果是false
{} == {} ------> false ---->引用类型数据存在堆中,栈中存储的是地址,所以比较的结果是false
!{} == {} -----> !Boolean([]) =={}.valueOf().toString() -----> false == '[object Object]' -----> Number(false ) == Number( '[object Object]') ---> 0 == NaN -----> false