一文搞懂js中的隐式类型转换
前言
今天来详细了解一下javascript
中的隐式类型转换,通过在各种情况下发生的隐式类型的例子,来详细的了解隐式类型转换的过程。
如何转换-前置知识
1.对象类型转换
当对象类型进行类型转换时,会调用js内部一个方法toPrimitive
, 此方法接收两个参数,一个参数为需要转换的对象,另一个方法接收一个期望类型,string
或number
。
- 当期望值为
number
时- 会调用
valueOf
方法,如果返回的值不是原始值,则继续调用toString
方法。
- 会调用
- 当期望值为string时
- 会调用
toString
方法,如果返回的值不是原始值,则继续调用valueOf
方法。
- 会调用
valueOf方法
对象 | 返回值 |
---|---|
Array | 返回数组对象本身。 |
Boolean | 布尔值。 |
Date | 存储的时间是从 1970 年 1 月 1 日午夜开始计的毫秒数 UTC。 |
Function | 函数本身。 |
Number | 数字值。 |
Object | 对象本身。这是默认情况。 |
String | 字符串值。 |
Math 和 Error 对象没有 valueOf 方法。 |
toString方法
对象 | 返回值 |
---|---|
Array | 逗号分隔的字符串 |
Boolean | 'true'或'false' |
Date | 美式英语日期格式的字符串 |
Function | 函数字符串 |
Number | 转为字符串 |
Object | "[object Object]" |
Math | "[object Math]" |
RegExp | 正则表达式的字符串 |
Error | "function Error() { [native code] }" |
2.原始类型转为number
原始数据类型 | 转换之后的值 |
---|---|
数字类型 | 不做任何改变 |
空字符 | 0 |
非空字符串 | 将字符内的数据内容变为数据,如果还有其他符号中文等转为NaN |
true | 1 |
false | 0 |
null | 0 |
undefined | NaN |
NaN | NaN |
3.原始类型转为string
原始数据类型 | 转换之后的值 |
---|---|
数字类型 | 数字类型的字符表示 |
字符串 | 不做任何改变 |
null | ‘null’ |
undefined | ‘undefined’ |
null | 0 |
undefined | NaN |
布尔类型 | true变’true’,false变’false’ |
4.其他类型转为boolean
原始数据类型 | 转换之后的值 |
---|---|
数字 0 | false |
非0数字 | true |
NaN | false |
空字符 | false |
null | false |
undefined | false |
非空字符串 | true |
非null对象类型 | true |
什么情况下会发生隐式类型转换
1. +
号
+
号比较特殊,既可以当做算数运算符做加法,又可以当做字符串连接符
- 1.1 算数运算符 (除
string
类型外的原始数据类型进行加法运算时)- 非数字类型,会转为数字类型
例:
1+null
//1
1+undefined
//NaN
1+true
//2
true + null
//1
true + undefined
//NaN
- 1.2 字符串连接符(
string
类型以及引用数据类型时)- 非
string
类型会转为string
类型
- 非
例:
[]+[]
//""
[]+{}
//"[object Object]"
true+[]
//"true"
true+{}
//"true[object Object]"
undefined+[]
//"undefined"
undefined + {}
//"undefined[object Object]"
解析:
- 进行算术运算时,原始数据类型转为数字使用
Number()
方法(例如:null
、boolean
、undefined
等) - 进行字符串连接时,引用数据类型会调用自身
toString
方法,如果返回不是原始值,会继续调用自身valueOf
方法,非引用数据类型:v.isString()
如果是true
,它将调用v.toString()
。否则,它将值转换为字符串。
2. 除加号以外的算数运算符(- * /)
- 非数字类型会转为数字类型
- 如果是原始数据类型会调用
Number()
方法进行转换 - 如果是引用数据类型会调用自身
valueOf
方法进行转换,如果转换后不是原始值,则会调用toString
方法进行转换,如果转换后不是数字,则会调用Number()
进行转换,如果转换后不是数字则会返回NaN
。
- 如果是原始数据类型会调用
10-'1'
// 9
10-true
// 9
10-[]
//10
10-null
//10
10-undefined
//NaN
10-{}
//NaN
3.逻辑运算符(&& || !)
- 非布尔类型会转为布尔类型
a&&b
如果a
为true
,则会返回b
;如果a
为false
,则会返回a
a||b
如果a
为true
,则会返回a
;如果a
为false
则会返回b
!a
如果a
为布尔值,则直接取反,如果a为非布尔值,则会转换为布尔值然后取反- 引用数据类型转换为布尔值后总会是
true
1&&2
//2
[]&&2
//2
2&&{}
//{}
![]
//false
!{}
//false
小技巧:
!!a
,会直接将非布尔值转换为布尔类型的值。
!!{}
//true
!![]
//true
!!0
//false
4.条件判断if()等
- 将括号内的值转为布尔类型
if({}){
console.log(1)
}
//1
if(null){
console.log(1)
}else{
console.log(2)
}
//2
5.比较运算符==、>、<等
null
与undefined
进行==
比较时不会进行转换,总返回true
。- 引用数据类型,会先转换为
string
(先调用valueOf
,后调用toString
),再转换为number
- 如果
==
左右都是引用数据类型,会进行地址比较
undefined==null
//true
0==[]
//true
[]==[]
//false 两个数组的地址指向不同
结尾
在众多的优秀框架方便我们开发的同时,还是需要多了解一些原生js的知识,打铁还需自身硬,共勉。
转载自:https://juejin.cn/post/6907822167853891597