前言
在上一章讲了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.得到结果:0
3. 转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
语句或 &&
、||
运算符