数值转换
有三个函数可以将非数值转换为数值:Number()、parseInt()、parseFloat()。Number()是转型函数,可用于任何数据类型。后两个函数主要用于将字符串转换为数值。
隐式类型转换
- 涉及类型转换最多的两个运算符是+和==。+可以是字符串相加,也可以是数字相加,在操作符中存在字符串时,优先转换为字符串。
- −∗/- * /−∗/ 只针对Number类型,所以转换的结果只能是Number类型。
三种转换
转换为数字
ES定义所有对象都有
toString()
方法,无论它是伪对象还是对象。
参数 结果 string 解析为数字,含有除了数字之外的字符,则转换为NAN boolean true->1 false->0 undefined NAN null +0 [] +0 [5] 5 {} NAN ‘111’ 111 空字符串转为0 含有字符的字符串转为NaN Symbol 报错
转换为字符串
参数 | 结果 |
---|---|
boolean | true->‘true’ false->‘false’ |
undefined | ‘undefined’ |
null | ‘null’ |
Number | 直接转换,例如123->‘123’ |
[] | “” |
[5,2] | “5.2” |
{} | ‘[Object Object]’ |
Symbol | ‘Symbol()’ |
转换为布尔值
参数 | 结果 |
---|---|
string | 除了空串都是’true’ |
undefined | false |
null | false |
Number | 除了+0 -0 NaN之外其他都为true |
[] | true |
{} | true |
Symbol | true |
===的判断
- ===属于严格相等,直接判断两者的类型是否相同,不同则返回fals
- 如果相同再比较大小,
不会进行任何隐式转换
- 对于引用类型来说,比较的都是引用内存地址,所以===这种方式的比较,除非两者存储的内存地址相同才相等,反之false
==涉及的类型转换规则
- 两边的类型是否相同,相同的话就比较值的大小。
- 判断是否是null和undefined,是的话就返回true。
- 判断类型是否是String和Numner,是的话就把String类型转成Number,再比较。
- 判断一方是否是Boolean,是的话就把Boolean转换成Number,再进行比较。
- 如果其中一方是Object,且另一方为String、Number或者Symbol,会将Object转换成字符串,再进行比较。
[]==![]
- 首先将![]转为布尔值,[]->true,!true->false,false->0
- []->0 故0==0,返回true。
对象转原始类型是根据什么流程运行的?
对象转原始类型,会调用内置的[ToPrimitive]函数,对于该函数,其逻辑如下:
- 如果Symbol.toPrimitive()方法,优先调用再返回
- 调用valueof(),如果转换为原始类型就返回
- 调用toString(),如果转换为原始类型就返回
- 如果都没有返回原始类型,会报错
并非所有对象的隐式转换都会按照这个流程进行,Date对象
会优先尝试toString方法来实现转换,非Date对象按照上述顺序。
类型 | valueOf | toString |
---|---|---|
Object | 对象本身,这是默认情况 | 返回’[object ObjectName]',其中ObjectName是对象类型的名称 |
String | 字符串值 | 返回String对象的值 |
Number | 数字值 | 返回数值的字符串表示、还可以返回指定进制表示的字符串 |
Boolean | Boolean值 | 为true,返回’true’;为false,返回’false’ |
Array | 数组本身 | 将Array的每个元素转为字符串,并将他们依次连接起来,两个元素之间用英文逗号作为分隔符进行拼接 |
Date | 存储的时间是从1970年1月1月午夜开始计的毫秒数UTC | 返回日期的文本表示 |
Function | 函数本身 | 返回如下格式的字符串,其中functionname是一个函数的名称,此函数的toString()方法被调用:“function functionname(){[native code]}” |
例子
({} + {})
- 进行ToPrimitive转换,由于没有指定PreferredType类型,{}会使默认值为Number,进行ToPrimitive(input, Number)运算。
- 执行valueOf方法,({}).valueOf(),返回的还是{}对象,不是原始值。
- 继续执行toString方法,({}).toString(),返回"[object Object]“,是原始值。 故得到最终的结果,”[object Object]" + “[object Object]” = “[object Object] [object Object]”
2 * {}
首先*运算符只能对number类型进行运算,故第一步就是对{}进行ToNumber类型转换。
- 由于{}是对象类型,故先进行原始类型转换,ToPrimitive(input, Number)运算。
- 执行valueOf方法,({}).valueOf(),返回的还是{}对象,不是原始值。
- 继续执行toString方法,({}).toString(),返回"[object Object]",是原始值。
- 转换为原始值后再进行ToNumber运算,"[object Object]"就转换为NaN。 故最终的结果为 2 * NaN =NAN
参考:《可能发生隐式类型转换的场景以及转换原则,应如何避免或巧妙应用》
ps:文末附上汇总文章链接《一名【合格】前端工程师的自检清单【自检ing】》