JavaScript == 运算符的机制

通过图形化方式理解 == 运算符的类型转换规则

问题

JavaScript 中 == 运算符的类型转换规则是什么?

解答

类型基础

JavaScript 的值分为两大类:

  • 原始类型:Undefined、Null、Boolean、Number、String
  • 对象类型:Object

所有对象都继承了 valueOf()toString() 方法,用于类型转换。

核心转换规则

考虑表达式 x == y,当 x 和 y 类型不同时:

1. Undefined 和 Null

undefined == null  // true
undefined == 0     // false
null == 0          // false

undefinednull 只与彼此相等,与其他值比较都返回 false

2. Boolean 转换

布尔值会先转为数字:

true == 1   // true (true 转为 1)
false == 0  // true (false 转为 0)
true == 2   // false

3. String 和 Number

字符串转为数字后比较:

'123' == 123      // true
'' == 0           // true (空字符串转为 0)
'123abc' == 123   // false (转换结果为 NaN)

转换规则:去除两端空白字符,尝试解析为合法数字,失败则返回 NaN

4. Object 转 Primitive

对象通过 ToPrimitive 操作转为原始值:

  • 先调用 valueOf(),如果返回原始值则使用
  • 否则调用 toString(),如果返回原始值则使用
  • 都不是原始值则抛出异常

例外:Date 对象先调用 toString()

[''] == false
// 步骤1: false 转为 0
// [''] == 0
// 步骤2: [].valueOf() 返回自身,继续调用 [].toString() 得到 ''
// '' == 0
// 步骤3: '' 转为 0
// 0 == 0
// 结果: true

完整规则图

所有类型转换都遵循以下趋势:

Object → Primitive → Number
Boolean → Number
String → Number

最终可归纳为 4 条规则:

  1. undefined == nulltrue,它们与其他值比较都是 false
  2. String == Boolean 时,两边都转为 Number
  3. String/Boolean == Number 时,String/Boolean 转为 Number
  4. Object == Primitive 时,Object 转为 Primitive

常见示例

// 规则1
undefined == null        // true
undefined == false       // false

// 规则2
'1' == true             // true ('1' → 1, true → 1)

// 规则3
'123' == 123            // true
false == 0              // true

// 规则4
[1] == 1                // true ([1].toString() → '1' → 1)
[1,2] == '1,2'          // true ([1,2].toString() → '1,2')

关键点

  • undefinednull 只与彼此相等,与其他值比较都是 false
  • Boolean 类型参与比较时会转为数字(true → 1,false → 0)
  • 对象转原始值的顺序是先 valueOf()toString()(Date 例外)
  • 所有类型转换最终都趋向于转成 Number 进行比较
  • 实际开发中建议使用 === 避免隐式类型转换带来的困惑