JavaScript 隐式类型转换

84 阅读2分钟

加法运算

核心规则

  1. 如果任意操作数是字符串:执行字符串连接。
  2. 如果所有操作数都是非字符串:尝试转换为数字后相加。
  3. 对象/数组的转换:优先调用 valueOf(),若无有效原始值则调用 toString()

总结表

操作数组合转换规则结果示例
字符串 + 任意类型全转字符串后连接"5" + 1 → "51"
数字 + 布尔/null转数字后相加10 + true → 11
数字 + undefinedundefinedNaN10 + undefined → NaN
对象/数组 + 非对象对象转原始值再运算[] + 1 → "1"
多个操作数从左到右逐步转换1 + 2 + "3" → "33"

示例

// 数字 + 非字符串 → 数字相加
10 + true;    // 11(true → 1)
10 + null;    // 10(null → 0)
10 + undefined; // NaN(undefined → NaN)

// 对象/数组的转换
[] + 1;       // "1"([] → "" → 字符串连接)
[1, 2] + 3;   // "1,23"(数组转字符串 "1,2")
{} + [];       // 0({} 被解析为空代码块,实际计算 +[] → 0)
({} + []);     // "[object Object]"(明确对象运算)

// 布尔值参与运算
true + false; // 1(布尔值转数字)
true + "!";   // "true!"(布尔值转字符串)

// null 和 undefined
null + null;      // 0(转数字)
undefined + 10;   // NaN(undefined → NaN)
null + " text";   // "null text"

非严格相等

核心转换规则(优先级从高到低)

  1. 类型相同:直接比较值(行为与 === 相同)

    5 == 5     // true
    "a" == "a" // true
    
  2. 字符串 vs 数字:将字符串转为数字

    "5" == 5   // true (Number("5") → 5)
    "" == 0    // true (Number("") → 0)
    
  3. 布尔值 vs 其他:将布尔值转为数字

    true == 1    // true (Number(true) → 1)
    false == 0   // true (Number(false) → 0)
    true == "1"  // true (true→1, "1"→1)
    
  4. 对象 vs 原始值:调用对象的 valueOf()toString() 转为原始值

    [1] == 1      // true ([1].toString() → "1" → 1)
    [1] == "1"    // true
    [] == 0       // true ([]→""→0)
    
  5. 其他组合:尝试转为数字比较

    true == []    // false (true→1, []→0 → 1 != 0)
    

特殊转换场景

  1. nullundefined:互相宽松相等,和其他任何相比都不相等

    null == undefined  // true
    undefined == null  // true
    
  2. NaNNaN:不相等,和其他任何相比也都不相等

总结表

比较场景转换规则示例结果
null vs undefined直接相等null == undefinedtrue
字符串 vs 数字字符串 → 数字'5' == 5true
布尔值 vs 任意布尔值 → 数字true == 1true
对象 vs 非对象对象 → 原始值 → 数字[1] == 1true
null/undefined vs 其他不转换null == 0false
数字 vs 非布尔原始值尝试转为数字true == '1'true

附加知识

SameValue

SameValue 和 SameValueZero 是 JavaScript 中的两种比较算法

SameValue:

Object.is() 使用此算法,此算法和 === 基本一致,但有两点不同

Object.is(NaN, NaN) // true
Object.is(0, -0) // false

SameValueZero:

Array.includes()Set.has() 使用此算法,此算法和 SameValue 的区别在于 +0 和 -0 是相等的

const s = new Set()
s.add(0)
s.add(NaN)
s.has(-0) // true
s.has(NaN) // true