一、什么是隐式转换
所谓隐式转换,就是我们在写代码时看不见,但是JavaScript解释器会自动帮我们转换的操作
隐式转换的本质是通过ToPrimitive将值转化为原始值,主要涉及到三种转换:
1.将值转为原始值 ToPrimitive()
2.将值转为数字 ToNumber()
3.将值转为字符串 ToString()
二、基本类型的隐式转换
1. +号
①数字+字符串 =>字符串
console.log(1+2+'3'); //'33'
//拓展其他数据类型
console.log(true + '6'); //'true6'
console.log(false + '6'); //'false6'
console.log(null + '6'); //'null6'
console.log(undefined + '6'); //'undefind6'
②数字加数字 =>数字
console.log(1+2+3); //6
//拓展其他数据类型
console.log(true + 6); //7
console.log(false + 6); //6
console.log(null + 6); //6
console.log(undefined + 6); //NaN
2. -号 (*、/、<、>)与-号同样方式转化
①数字-字符串 =>数字
console.log(10 - '20');//-10
console.log(10*'20'); //200
console.log('20'/'10'); //2
②数字-非数字字符串 =>NaN
console.log(10 - 'one' ); //NaN
console.log(10 - '100a'); //NaN
console.log('20'/'one'); //NaN
三、有关==的隐式转换
双等符号的隐式转换很简单,只要记住,不管是什么基本类型的数据,都会转化成数字类型比较,话不多说,看代码
console.log('0' == 0); //true 字符串转数字
console.log(0 == false); //true 布尔转数字
console.log('0' == false); //true 两者转数字
// undefined和null比较特殊
console.log(undefined == null); //true
四、引用类型的隐式转换
引用类型的隐式转换有些复杂,但是大致思路就是先将引用类型转化为基本类型,然后再按照基本类型的方式转化,那么,我们该怎么让引用类型转化为基本类型呢?
其实,在JavaScript中,引用数据类型的隐式转化遵循PreferredType转换策略,分为以下两种情况:
1.如果PreferredType被标记为Number
①如果输入的值已经是一个原始值,则直接返回它
②如果输入的值是一个对象,则调用该对象的valueOf()方法, 如果valueOf()方法的返回值是一个原始值,则返回这个原始值
③调用这个对象的toString()方法,如果toString()方法返回的是一个原始值,则返回这个原始值。
④否则,抛出TypeError异常
2.如果PreferredType被标记为String
①如果输入的值已经是一个原始值,则直接返回它
②如果输入的值是一个对象,则调用该对象的toString()方法, 如果toString()方法的返回值是一个原始值,则返回这个原始值
③调用这个对象的valueOf()方法,如果valueOf()方法返回的是一个原始值,则返回这个原始值。
④否则,抛出TypeError异常
注意:PreferredType的值的设置规则
1、该对象为Date类型,则PreferredType被设置为String
2、否则,PreferredType被设置为Number
来看几个特殊的例子:
// 引用数据类型的隐式转换
console.log([] + []); 结果为 "" + "" = ""
// 1.确定 [] PreferredType 为 number
// 2.确定 [] 不是原始值
// 3.调用 valueOf 方法
console.log([].valueOf(),typeof [].valueOf());
// 4.调用 toString 方法
console.log([].valueOf().toString(),typeof [].valueOf().toString());
// 5.最终 [] 隐式转换 => '' 空的字符串
console.log([] + {}); 结果为 "" + "[object Object]" = "[object Object]"
// 1.确定 {} PreferredType 为 number
// 2.确定 {} 不是原始值
// 3.调用 valueOf 方法
console.log({}.valueOf(),typeof {}.valueOf());
// 4.调用 toString 方法
console.log({}.valueOf().toString(),typeof {}.valueOf().toString());
// 5.最终 {} 隐式转换 => "[object Object]"
{} + [] 隐式转换结果为0
// {} + [] => {}; +[]
// js会将{};看成代码块略过,所以就只剩 +[]
// +[] => +"" => +false => +0 => 0
// 但是{} + []在终端的打印结果是[object Object] 是string类型
// 在浏览器控制台又输出 0
console.log({} + [],typeof ({} + []));
// {} + {} 隐式转换结果为"[object Object][object Object]"
console.log({} + {});