JavaScript 中的隐式类型转换主要发生在+、-、*、/以及==、>、<这些运算符之间。而这些运算符只能操作基本类型值,所以在进行这些运算前的第一步就是将两边的值用ToPrimitive转换成基本类型,再进行操作。
ToPrimitive方法是js中每个值隐含自带的方法,用来将值(无论是基本类型还是对象)转换为基本类型值。如果值为基本类型,直接返回值本身;如果值为对象,
ToPrimitive(obj,type)
如果对象是Date对象,type默认为string
其他一律默认为number
(1)当
type
为number
时规则如下:
- 调用
obj
的valueOf
方法,如果为原始值,则返回,否则下一步;- 调用
obj
的toString
方法,后续同上;- 抛出
TypeError
异常。
var objToNumber = value => Number(value.valueOf().toString())
objToNumber([]) === 0
objToNumber({}) === NaN
(2)当
type
为string
时规则如下:
- 调用
obj
的toString
方法,如果为原始值,则返回,否则下一步;- 调用
obj
的valueOf
方法,后续同上;- 抛出
TypeError
异常。
1.+
当两边有一个string,就会变字符串,其他情况两边都变数字
1 + '23' // '123' 1 + false // 1 1 + Symbol() // Uncaught TypeError: Cannot convert a Symbol value to a number '1' + false // '1false' false + true // 1
2 -,*,/
NaN也是一个数字
1 * '23' // 23 1 * false // 0 1 / 'aa' // NaN
3 ==
两边都尽量转成number
3 == true // false, 3 转为number为3,true转为number为1 '0' == false //true, '0'转为number为0,false转为number为0 '0' == 0 // '0'转为number为0
4 < >
若两边都是字符串,比较字母表顺序
其他情况都转number
'ca' < 'bd' // false 'a' < 'b' // true
'12' < 13 // true false > -1 // true
5 对象
例如:
var a = {} a > 2 // false //分析 a.valueOf() // {}, 上面提到过,ToPrimitive默认type为number,所以先valueOf,结果还是个对象,下一步 a.toString() // "[object Object]",现在是一个字符串了 Number(a.toString()) // NaN,根据上面 < 和 > 操作符的规则,要转换成数字 NaN > 2 //false,得出比较结果
再比如
var a = {name:'Jack'} var b = {age: 18} a + b // "[object Object][object Object]" //分析 a.valueOf() // {},上面提到过,ToPrimitive默认type为number,所以先valueOf,结果还是个对象,下一步 a.toString() // "[object Object]" b.valueOf() // 同理 b.toString() // "[object Object]" a + b // "[object Object][object Object]"