首先要介绍ToPrimitive方法,这是 JavaScript 中每个值隐含的自带的方法,用来将值 (无论是基本类型值还是对象)转换为基本类型值。如果值为基本类型,则直接返回值本身;如果值为对象,其看起来大概是这样:
type的值为number或者string。
1. 当type为number时规则如下:
调用obj的valueOf方法,如果为原始值,则返回,否则下一步;调用obj的toString方法,后续同上;抛出TypeError 异常。
2. 当type为string时规则如下:
调用obj的toString方法,如果为原始值,则返回,否则下一步;调用obj的valueOf方法,后续同上;抛出TypeError 异常。
可以看出两者的主要区别在于调用toString和valueOf的先后顺序。默认情况下:
如果对象为 Date 对象,则type默认为string;其他情况下,type默认为number。
总结上面的规则,对于 Date 以外的对象,转换为基本类型的大概规则可以概括为一个函数:
而 JavaScript 中的隐式类型转换主要发生在+、-、*、/以及==、>、<这些运算符之间。而这些运算符只能操作基本类型值,所以在进行这些运算前的第一步就是将两边的值用ToPrimitive转换成基本类型,再进行操作。
以下是基本类型的值在不同操作符的情况下隐式转换的规则 (对于对象,其会被ToPrimitive转换成基本类型,所以最终还是要应用基本类型转换规则):
1. +操作符 +操作符的两边有至少一个string类型变量时,两边的变量都会被隐式转换为字符串;其他情况下两边的变量都会被转换为数字。
2. -、*、\操作符
NaN也是一个数字
3. 对于==操作符
操作符两边的值都尽量转成number:
4. 对于<和>比较符
如果两边都是字符串,则比较字母表顺序:
其他情况下,转换为数字再比较:
以上说的是基本类型的隐式转换,而对象会被ToPrimitive转换为基本类型再进行转换:
其对比过程如下:
又比如:
运算过程如下: