likes
comments
collection
share

一文搞懂js中的隐式类型转换

作者站长头像
站长
· 阅读数 2

前言

今天来详细了解一下javascript中的隐式类型转换,通过在各种情况下发生的隐式类型的例子,来详细的了解隐式类型转换的过程。

如何转换-前置知识

1.对象类型转换

当对象类型进行类型转换时,会调用js内部一个方法toPrimitive, 此方法接收两个参数,一个参数为需要转换的对象,另一个方法接收一个期望类型,stringnumber

  • 当期望值为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
true1
false0
null0
undefinedNaN
NaNNaN

3.原始类型转为string

原始数据类型转换之后的值
数字类型数字类型的字符表示
字符串不做任何改变
null‘null’
undefined‘undefined’
null0
undefinedNaN
布尔类型true变’true’,false变’false’

4.其他类型转为boolean

原始数据类型转换之后的值
数字 0false
非0数字true
NaNfalse
空字符false
nullfalse
undefinedfalse
非空字符串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()方法(例如:nullbooleanundefined等)
  • 进行字符串连接时,引用数据类型会调用自身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 如果atrue,则会返回b;如果afalse,则会返回a
    • a||b 如果atrue,则会返回a;如果afalse则会返回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.比较运算符==、>、<等

  • nullundefined进行==比较时不会进行转换,总返回true
  • 引用数据类型,会先转换为string(先调用valueOf,后调用toString),再转换为number
  • 如果==左右都是引用数据类型,会进行地址比较
undefined==null
//true
0==[]
//true
[]==[]
//false 两个数组的地址指向不同

结尾

在众多的优秀框架方便我们开发的同时,还是需要多了解一些原生js的知识,打铁还需自身硬,共勉。