JavaScript中的类型转换机制分为显示转换和隐式转换。
一、显示类型转换
显示类型转换(强制类型转换),是开发者主动调用函数或方法进行转换,常见的方法有:
- String()
- Number()
- Boolean()
1. String()
用于将任意类型值转换为字符串。使用方法String(x)
或x.toString()
。
规则:
- 数字 → 字符串(如String(3.14) → ‘3.14’)
- true → ‘true’, false → ‘false’
- null → ‘null’
- undefined → ‘undefined’
- 对象 → 调用其
toString()
方法(如String({a:1}) → ‘[object Object]’、[1,2].toString()→'1,2'
) - 函数(对象) → 调用其
toString()
方法(如String(function(){}) → ‘function (){}’)
验证:
2. Number()
用于将任意类型值转换为数字。使用方法Number(x)
、parseInt(x)
。
规则:
- 字符串
- 空字符串或纯空格 →
0
(Number(“”) → 0
) - 纯数字字符串 → 数字(
Number('123') → 123
,parseInt('123') → 123
) - 数字开头的字符串 → Number()转为为
NaN
(Number('123abc') → NaN
)/parseInt()截取数字那部分,(parseInt('123abc') → 123
) - 非数字开头的字符串 →
NaN
(Number('abc') → NaN
,parseInt('abc') → NaN
)
- 空字符串或纯空格 →
- 布尔值
true
→1
false
→0
null
→0
undefined
→NaN
- 对象 → 调用其
valueOf()
方法,若结果非原始值则调用toString()方法,再转数字。(如Number({a:1}) → NaN) - 数组(补充)
- 空数组 →
0
(Number([]) → 0
) - 非空数组(单个值) →
NaN
(Number([1]) → 1
) - 非空数组(多个值) →
NaN
(Number([1,2]) → NaN
)
- 空数组 →
验证:
3. Boolean()
用于将任意类型值转换为布尔值。使用方法Boolean(x)
或!!x
。
规则:
- Falsy(转布尔为
false
)false
0
NaN
null
undefined
""
- 其他所有值均为
true
"0"
"false"
[]
{}
- 等等
验证:
二、隐式类型转换
隐式类型转换是Javascript引擎自动触发的类型转换,常见的常见有:
+
运算符-
,*
,/
,%
运算符- 比较运算符(
==
,>
等) - 逻辑操作(
if
、&&
、||
等)
1. +
运算符
规则:
- 若一侧为字符串,另一侧转字符串(如
1 + '2' → '12'
,null + '3' → 'null3'
) - 若一侧为对象,先调用对象的
valueOf
,若结果非原始值,在调用toString()
进行计算(如[] + 1 → '1'
) - 其他情况转数字(如
1 + true → 2
,1 + null → 1
)
[] + 1 → '1'
过程说明:
- 先将对象(
[]
)转换为原始值- 优先调用
valueOf()
方法,若结果非原始值则调用toString()
方法(数组valueOf()
返回的是数组本身,非原始值) - 继续调用
toString()
方法,数组的toString()
方法会将其元素用逗号连接成字符串。(空数组的toString()
等于"")
- 优先调用
- 转换后变成"" + 1
- 满足上述
规则1
,所以结果为"1"
验证:
2. -
,*
,/
,%
运算符
规则:
- 一律转为数字,再进行计算(如
'5' - '3' → 2
,'abc' * 2 → NaN
,false / 2 → 0
)
验证:
3. 比较运算符(==
, >
等)
规则:
null == undefined → true
(仅两者互等)- 字符串与数字比较,字符串转数字(如
'1' == 1 → true
) - 布尔值与其他类型比较,布尔值转数字(如
true == 1 → true
) - 对象与原始值比较,对象转原始值(优先
valueOf()
,再toString()
如[1] == 1 → true
)
验证:
4. 逻辑操作(if
、&&
、||
等)
规则:
- 条件判断自动转布尔值(如
if(0) {} → false
,if({}) {} → true
)
三、对象到原始值的转换
对象转原始值时,优先调用 valueOf() 和 toString():
- 默认行为
- valueOf():默认返回对象自身。
- toString():返回 [object Object](对象)或逗号分隔元素(数组)。
- 转换场景
- 转字符串(如 alert(obj)):优先调用 toString()。
- 转数字(如 +obj 或数学运算):优先调用 valueOf(),失败则调用 toString() 后转数字。
- 示例:
- {} + 1 → 1(对象转数字为 NaN,但此处被解析为代码块,实际计算 +1)。
- [] + 1 → “1”(数组转空字符串,再拼接1)。
四、特殊案例
Date
对象
- 转字符串:
new Date().toString() → "Wed Jul 12 2023 ..."
- 转数字:+
new Date() → 时间戳
(因valueOf()返回时间戳)。
- NaN 的陷阱
NaN
是唯一不等于自身的值:NaN === NaN → false
,需用Number.isNaN(x)
检测。 - 经典面试题
- [] == ![] → true
- ![] 转布尔为
false
→ 转数字0
。 - [] 转数字:
v
alueOf()返回数组本身 → 调用
toString()得空字符串 → 转数字
0`。 - 最终比较
0 == 0 → true
。
- ![] 转布尔为
五、总结
- 显式转换:主动使用 String()/Number()/Boolean()。
- 隐式转换:关注运算符和上下文(如+拼接字符串、==的自动转换)。
- 对象转换:优先 valueOf(),再 toString(),Date对象特殊处理。
- 避免隐式转换陷阱:优先使用 ===,必要时显式转换。