JavaScript 隐式类型转换的 6 大核心场景
一、使用 == 宽松相等比较时
// 经典面试题[] == ![] // true// 转换路径:// 1. ![] → false(空数组转布尔为true,取反后为false)// 2. [] == false → [] == 0// 3. [].valueOf() → [](非原始值),调用 toString() → ""// 4. "" == 0 → 0 == 0 → true// 5. true == '1' → true == 1 → true转换优先级表
| 比较双方类型 | 转换规则 |
|---|---|
| Number vs String | String → Number |
| Boolean vs 其他类型 | Boolean → Number |
| Object vs 原始类型 | Object → 原始值(优先 valueOf → toString) |
| null vs undefined | 直接相等 |
二、算术运算符操作时
1. 加法运算符 +
"5" + 2 = "52" // 字符串优先拼接"5" - 2 = 3 // 转换为数字运算[] + {} = "[object Object]" // [] → "", {} → "[object Object]"2. 其他运算符 - * / %
"10" - "2" = 8 // 转为数字运算"10a" * 2 = NaN // 转换失败返回 NaN三、逻辑判断中的真值转换
if (0) { /* 不执行 */ } // 0 → falsewhile ("") { /* 不执行 */ } // "" → falseconst val = null;console.log(val || "default"); // null → false,输出 "default"Falsy 值列表
| 值 | 转换结果 |
|---|---|
| 0, -0 | false |
| "" | false |
| null | false |
| undefined | false |
| NaN | false |
四、模板字符串嵌入变量时
const obj = { toString: () => "OBJ" };console.log(`Value: ${obj}`); // "Value: OBJ"(自动调用 toString)五、对象参与原始值操作时
const date = new Date();// 优先调用 toString()console.log("Today is " + date); // "Today is Wed Oct 18 2023..."
// 优先调用 valueOf()console.log(date * 1); // 输出时间戳(数值运算)对象转换优先级
- 检查
Symbol.toPrimitive方法 - 数值上下文优先调用
valueOf() - 字符串上下文优先调用
toString()
六、数组的特殊转换行为
// 数组转字符串[1, 2] + [3, 4] = "1,23,4" // 数组 → "1,2" + "3,4"
// 空数组转换[] == 0 // true([] → "" → 0)Number([]) // 0Boolean([]) // true(所有对象转布尔都是true)防御式编程建议
- 严格模式:始终使用
===代替== - 显式转换:用
Number(),String(),Boolean()明确意图 - 类型守卫:对函数参数进行类型校验
function sum(a, b) {if (typeof a !== "number" || typeof b !== "number") {throw new Error("参数必须为数字");}return a + b;}