一、什么情况会发生隐式类型转换?
1、加号(+)
+号比较特殊,既可以当做算数运算符做加法,又可以当做字符串连接符
① 算数运算符
除了 string 类型以外的原始数据类型进行加法运算时,非数字类型会转换为数字类型。
进行算术运算时,原始数据类型转为数字,使用 Number() 方法。
console.log(1 + 1) // 2
console.log(1 + undefined) // NaN
console.log(1 + null) // 1
console.log(null + undefined) // NaN
console.log(true + false) // 1
console.log(true + 1) // 2
② 字符串连接符
当含有string类型和引用数据类型时,+号会作为字符串连接符使用,非string类型会转换为string类型。
引用数据类型:会调用自身 toString 方法,如果返回不是原始值,会继续调用自身 valueOf 方法;
非引用数据类型:v.isString() 如果是true,它将调用v.toString()。否则,它将值转换为字符串
console.log(1 + '2') // '12'
console.log('2' + '2') // '22'
console.log('1' + true) // '1true'
console.log('1' + false) // '1false'
console.log('1' + undefined) // '1undefined'
console.log('1' + null) // '1null'
console.log('1' + NaN) // '1NaN'
console.log('2' + []) // '2'
console.log(2 + [1, 2]) // '21,2'
console.log(2 + { a: 1 }) // '2[object Object]'
console.log([] + {}) // '[object Object]'
console.log({} + []) // '[object Object]'
console.log(3 + {}) // '3[object Object]'
console.log({} + 3) // '[object Object]3'
console.log(true + []) // 'true'
console.log(true + {}) // 'true[object Object]'
console.log(undefined + {}) // 'undefined[object Object]'
2、除加号以外的算数运算符(- * /)
非数字类型会转换为数字类型;
原始数据类型:调用 Number() 方法进行转换;
引用数据类型:调用自身 valueOf 方法进行转换,如果转换后不是原始值,则会调用 toString 方法进行转换,如果转换后不是数字,则会调用 Number() 进行转换,如果转换后不是数字则会返回NaN
console.log(10 - 1) // 9
console.log(10 - '1') // 9
console.log(10 - null) // 10
console.log(10 - undefined) // NaN
console.log(10 - NaN) // NaN
console.log(10 - true) // 9
console.log(10 - false) // 10
console.log(10 - {}) // NaN
console.log(10 - {name: '草莓'}) // NaN
console.log(10 - [1,2]) // NaN
3、逻辑运算符(&& || !!!)
非布尔类型会转换为布尔类型,引用数据类型转换为布尔值后总会是 true
① !
!a,如果a为布尔值,则直接取反;如果a为非布尔值,则会转换为布尔值然后取反
② &&
a && b,如果a为true,则会返回b;如果a为false,则会返回a
③ ||
a || b,如果a为true,则会返回a;如果a为false,则会返回b
④ !!
!!a,会直接将非布尔值转换为布尔类型的值
console.log(![]) // false
console.log(!{}) // false
console.log(!1) // false
console.log(!0) // true
console.log(!undefined) // true
console.log(!null) // true
console.log(!'') // true
console.log(!NaN) // true
console.log(1 && 2) // 2
console.log([] && 2) // 2
console.log(2 && {}) // {}
console.log(2 || {}) // 2
console.log(false || {}) // {}
console.log('' || {}) // {}
console.log(!!{}) // true
console.log(!![]) // true
console.log(!!0) // false
console.log(!!1) // true
console.log(!!'') // false
4、比较运算符(== > < 等)
null与undefined进行==比较时,不会进行转换,总返回true
引用数据类型,会先转换为string(先调用valueOf,后调用toString),再转换为number
如果==左右都是引用数据类型,会进行地址比较;
NaN是唯一一个与自身不相等的值;
console.log(undefined == null) // true
console.log(undefined == '') // false
console.log(null == null) // true
console.log('' == null) // false
console.log(undefined == undefined) // true
console.log('' == '') // true
console.log(NaN == NaN) // false
console.log('' == NaN) // false
console.log(1 == '1') // true
console.log(0 == []) // true
console.log('1,2' == [1,2]) // true
console.log([] == []) // false
console.log([1, 2] == [1, 2]) // false
console.log({} == []) // false
console.log({} == {}) // false
二、类型转换
1、原始数据类型转为number:
2、原始数据类型转为string:
3、引用类型转为string:
4、所有类型转换为boolean: