隐式类型转换
隐式数据类型转换通常发生在比较大小,是否相等,加减乘除等运算、或当前运行环境的默认输出类型为固定值时。
例如:使用非严格相等操作符(==)判断两个值是否相等时,如果两个值的类型不同(typeof),会将两个值隐式的转化为相同的类型后再执行严格相等的比较。(其中一个或者两个值都发生类型转换)
1.原始类型之间的转换使用Number(),String(),Boolean()。
原始值 | 转化为数值类型 | 转化为字符串类型 | 转化为布尔类型 |
---|---|---|---|
false | 0 | “false” | |
true | 1 | “true” | |
+0或-0 | ‘’+0”或”-0” | false | |
1 | “1” | true | |
NAN | “NAN” | false | |
infinity | “infinity” | true | |
-infinity | “-infinity” | true | |
undefined | NAN | “undefined” | false |
null | 0 | “null” | false |
“” | 0 | false | |
“10” | 10 | true | |
“abcd” | NAN | true |
2.当引用类型转换为基本类型时则使用ToPrimitive函数。
1 | ToPrimitive(input, PreferredType?)的简单实现,代码来源于:https://zhuanlan.zhihu.com/p/29064256 |
原始值 | 转化为数值类型 | 转化为字符串类型 | 转化为布尔类型 |
---|---|---|---|
[] | 0 | “” | true |
[10] | 10 | “10” | true |
[1,2] | NaN | “1,2” | true |
[“10”] | 10 | “10” | true |
[“abcd”] | NaN | “abcd” | true |
function(){} | NaN | “function(){}” | true |
{} | NaN | “[object Object]” | true |
以下几种类型在转化为布尔值时为false,其它的均为true
null,undefined,0,””,NaN(共五种)
注意:如果使用new操作符创建的对象隐式转换为boolean类型都是true,哪怕是new String(”);
运行环境和操作符对隐式类型转换的影响
数据到底是被转化为number还是string受到运行环境和操作符的影响。
运行环境的影响
很多内置函数期望传入的参数的数据类型是固定的,如:alert(value)方法,它期望传入的value值是一个string类型,但是如果我们传入的是number类型或者object类型等非string类型的数据的时候,就会发生数据类型的隐式转换。这就是环境运行环境对数据类型转换的影响
操作符的影响
当+号作为一元操作符操作单操作数的时候,他就会将这个数转换为Number类型
当+号作为二元操作符时,如果两个操作数中存在一个String类型的话,那么另外一个操作数也会无条件地转换为字符串.
在第1步转换后,如果有运算元出现原始数据类型是”字符串”类型值时,则另一运算元作强制转换为字符串,然后作字符串的连接运算(concatenation)。
当+号作为二元操作符时,如果两个操作数一个都不是字符串的话,两个操作数会隐式转换成数字类型(如果无法成功转换成数字,则变成NaN,再往下操作),再进行加法算数操作.
当算数运算的操作符是+号以外的其他操作数时,两个操作数都会转成数字类型进行数字运算。
== 与!=操作符的运算规则
1 | x==y的判断 |
复杂对象转换原理
复杂对象是以什么标准来判断ToPrimitive(input,preferredType)操作传入的preferredType值到底是number还是string呢?(可以见上面代码部分,这里做个简单说明)
如果运行环境非常明确的需要将一个复杂对象转换为数字则传入number如 Number(value) 和 +value 则传入number
如果运行环境非常明确的需要将一个复杂对象转换为字符串则传入string如String(value) 和 alert(value) 则传入string
如果是用+号连接两个操作数,操作数在确定确定其中只要有一个为字符串的时候另外一个操作数会转为字符串,ToPrimitive()会传入string,但是如果两个操作数都不能确定是字符串的时候则默认传入number进行数据类型转换(Date对象是一个例外,它会默认传入string)。
ToPrimitive的转换示例
1 | ["12"]+1; //‘121’ |
首先对于这个引用类型preferredType参数默认会是number,这个时候调用传入对象的valueOf()方法,如果他的返回值类型是一个基本类型,那么就返回这个值,如果不是,则调用toString()方法,返回这个基本类型的值。