前言
在上一章讲了JavaScript中的数据类型以及类型判断的方法,接下来将来研究研究如何实现不同类型的相互转换,而类型转换主要含有两大部分:显式类型转换、隐式类型转换
原始值转原始值 ---显式类型转换
1. 转布尔 ---Boolean(x)
2. 转number ---Number(x)、parseInt() 或 parseFloat()
3. 转string字符串 ---String(x)以及.toString() 方法
原始类型转布尔的例子
            
            
              js
              
              
            
          
          let s = 's'
let n = 123
let f = false
let u = undefined
let nu = null
console.log(Boolean(s));//true
console.log(Boolean(n));//true //只有0是false,其他都是true
console.log(Boolean(''));//false
console.log(Boolean(Infinity));//true无穷大
console.log(Boolean(f));//false
console.log(Boolean(u));//false
console.log(Boolean(nu));//false
console.log(Boolean());//false,什么都没有就默认为false 其中要注意几点
- 函数内为数字类型时,只有
0会转换为false其余全转换为true- 函数内为
Infinity(表无穷大)或者为无穷小时,当作数字类型处理- 为空时就默认输出为false
原始类型转number的例子
            
            
              js
              
              
            
          
          console.log(Number('123'));//数字123
console.log(Number('123a'));//NaN不可描述的数字
console.log(Number(''));// 0
console.log(Number(true));//1
console.log(Number(false));//0
console.log(Number(null));//0
console.log(Number(undefined));//NaN
console.log(Number());//0
let intStr = "100";
let floatStr = "100.25";
let intNum = parseInt(intStr); // intNum 为 100
let floatNum = parseFloat(floatStr); // floatNum 为 100.25要注意
- 为
undefined和复杂原始类型时输出NaN即不可描述的数字
原始类型转string字符串的例子
            
            
              js
              
              
            
          
          console.log(String(123));//'123'
console.log(String(true));//'true'
console.log(String(false));//'false'
console.log(String(null));//'null'
console.log(String(undefined));//'undefined'
console.log(String());//''
console.log(String(Symbol()));//'Symbol()'
let bool = true; 
let strBool = bool.toString(); // bool 为 true,转换后 strBool 为 "true"将对象转原始值 ---隐式类型转换
隐式类型转换是指在执行某些操作时,JavaScript引擎自动将一个数据类型转换为另一个数据类型,而无需程序员显式地调用转换函数。这种转换有时也被称为强制类型转换或类型协变。
1. 转布尔
- 任何对象转布尔值,直接返回true
2. 转number
ToPrimitive: 这是JavaScript引擎内部的一个抽象操作,它负责将对象转换为原始值(字符串、数字、布尔值等)。此操作并不直接暴露为JavaScript的API,但在类型转换过程中起着核心作用。
在对象使用Number()函数转换时会有一下隐式的步骤
- 先调用ToNumber(x),该函数中会再调用ToPrimitive()将对象转为原始值
- ToPrimitive({obj},Number)- 判断接收到的值是不是原始类型,是则返回该原始值,直接下班
- 如果不是原始类型,则调用obj.valueOf(),如果得到了原始值,则返回该原始值
- 否则调用obj.toString(),如果得到了原始值,则返回该原始值
- 则报错
 
            
            
              js
              
              
            
          
          Number({})
1.ToNumber({})
2.let primValue = ToPrimitive({},Number)//[object,Object]
3.ToNumber("[object Object]")//NaN
4.得到结果:NaN
Number([])
1.ToNumber([])
2.let primValue = ToPrimitive([],Number)//''
3.ToNumber('')//0
4.得到结果:03. 转string字符串
在对象使用String()函数转换时会有一下隐式的步骤
- 先调用ToString(x),该函数中会再调用ToPrimitive()将对象转为原始值
- ToPrimitive({obj},String)- 判断接收到的值是不是原始类型,是则返回该原始值,直接下班
- 否则调用obj.toString(),如果得到了原始值,则返回该原始值
- 如果不是原始类型,则调用obj.valueOf(),如果得到了原始值,则返回该原始值
- 则报错
 
            
            
              js
              
              
            
          
          String({})
//隐式步骤
1.ToString({})
2.let primValue = ToPrimitive({},String)//"[object Object]"
3.ToString("[object Object]")//"[object Object]"
4.得到结果:"[object Object]"注意这里和转number的区别,是先调用obj.toString()
隐式转换的其他情况
除了对象到原始类型转换这种情况,隐式类型转换还经常发生在以下场景中:
1. 算术运算:
一元操作符 +
几元就代表加号左右两边有几个元素
+号 会触发隐式类型转换,往number转
            
            
              js
              
              
            
          
          +[]
1.ToNumber([])
2.let primValue = ToPrimitive([],Number)//''
3.ToNumber('')
4.得到结果 0
+{}
1.ToNumber({})
2.let primValue = ToPrimitive({},Number)//"[object,Object]"
3.ToNumber("[object,Object]")
4.得到结果 Nan二元运算符+
当参与运算的操作数不是同一类型时,某些值会被转换为数字。
- 例如,'3' + 2结果为'32'(字符串连接)。只要左右两边有一个是字符串,结果都是字符串
- 但 '3' - 2结果为1(字符串'3'被转换为数字3)。
            
            
              js
              
              
            
          
          1 + '1' //'11'只要左右两边有一个是字符串,结果都是字符串
1 + [] // 1 + '' = '1' 存在字符串依旧按照字符串的拼接规则,而不转为数字 1 + 0
{} + [] // "[object,Object]" + '' = "[object,Object]"2. 比较运算:
在比较操作中,不同类型的数据会被转换以进行比较。
- 如 true == 1结果为true,因为在比较前true被转换为1。
- null == undefined结果为- true,两者在比较时被视为相等。
== 与 ===的区别
- ==会触发隐式类型转换
- ===不会触发隐式类型转换,判断类型和值都相等,严格等于
            
            
              js
              
              
            
          
          1 == '1' // true
//1 == Number('1') 触发隐式转换
1 === '1' // false
- 使用==时会发生number类型的转换后在进行比较
- 当使用===时代表的是严格等于,即不会发生任何形式的转换,直接进行比较,既要类型相同,值也要相同
            
            
              js
              
              
            
          
          [] == ![] 
// !优先级更高
// [] == !ture
// [] == false
// [] == 0
// Number([]) == 0
// '' == 0
// 0 == 0
//得到true这段代码展示了JavaScript中一个经典的类型转换和比较链,最终结果为true。下面是对这一过程的详细解析:
- !优先级更高 : 首先执行- ![],这里的- !是一个逻辑非操作符,它会先于等号运算执行。对于一个非空数组- [],它被当作真值处理,因此- ![]会得到- false。
- [] == false: 接下来比较- [](空数组)和- false。在进行- ==比较时,JavaScript会尝试将两边的操作数转换为相同类型再比较。
- [] == 0: 因为直接比较数组和布尔值不是直观的比较,JavaScript会将两边都转换为数字类型进行比较。空数组- []转换为数字时,通过- Number([])实现,这一步会先调用数组的- toString()方法,得到空字符串- '',然后将这个空字符串转换为数字- 0。
- Number([]) == 0: 正如上一步所述,空数组转换为数字- 0。
- '' == 0: 现在比较空字符串- ''和数字- 0。空字符串在进行数值比较时会被转换为- 0。
- 0 == 0: 经过一系列转换后,最终比较的是- 0和- 0,显然结果为- true。
3. 逻辑运算:
在逻辑运算中,如 if 语句或 &&、|| 运算符,表达式会被转换为布尔值。
- 如 if ('text')会执行代码块,因为非空字符串被视为true。
总结
类型转换主要含有两大部分:显式类型转换、隐式类型转换
显式类型转换较为简便,只需要注意一种场景:原始值转原始值
隐式类型转换则需要注意更多的场合,将对象转原始值,算术运算中的+,比较运算的==和===,以及逻辑运算中的if 语句或 &&、|| 运算符