Skip to content

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 StringString → 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 → false
while ("") { /* 不执行 */ } // "" → false
const val = null;
console.log(val || "default"); // null → false,输出 "default"

Falsy 值列表

转换结果
0, -0false
""false
nullfalse
undefinedfalse
NaNfalse

四、模板字符串嵌入变量时

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); // 输出时间戳(数值运算)

对象转换优先级

  1. 检查 Symbol.toPrimitive 方法
  2. 数值上下文优先调用 valueOf()
  3. 字符串上下文优先调用 toString()

六、数组的特殊转换行为

// 数组转字符串
[1, 2] + [3, 4] = "1,23,4" // 数组 → "1,2" + "3,4"
// 空数组转换
[] == 0 // true([] → "" → 0)
Number([]) // 0
Boolean([]) // true(所有对象转布尔都是true)

防御式编程建议

  1. 严格模式:始终使用 === 代替 ==
  2. 显式转换:用 Number(), String(), Boolean() 明确意图
  3. 类型守卫:对函数参数进行类型校验
    function sum(a, b) {
    if (typeof a !== "number" || typeof b !== "number") {
    throw new Error("参数必须为数字");
    }
    return a + b;
    }