跳到主要内容

类型转换(隐式/显式)怎么解释?== 的规则是啥?

面试速答(30 秒版 TL;DR)

  • JS 类型转换本质是三步:ToPrimitive(先变原始值)ToNumber/ToString/ToBoolean(按上下文转换)
  • + 既可能做数字加法也可能做字符串拼接:只要有一边是字符串或能被转成字符串参与拼接,就走拼接。
  • == 会做隐式转换(宽松相等),规则很多且容易踩坑;工程上默认用 ===,只有在明确需要“nullundefined”同判时才用 x == null

心智模型:转换是“上下文驱动”

你需要能说清:为什么同一个值在不同位置表现不一样。

  • 条件判断(if (x))触发 ToBoolean
  • 数学运算(- * / % < > 等)触发 ToNumber
  • 字符串拼接(+ 且一侧是字符串倾向)触发 ToString
  • 对象参与比较/运算会先 ToPrimitive(调用 valueOf/toStringSymbol.toPrimitive

ToBoolean:哪些是假值(falsy)?

只有这 7 个是假值,其余都是真值(truthy):

  • false
  • 0-0
  • 0n
  • ""(空字符串)
  • null
  • undefined
  • NaN
if ([]){ /* 会进来:[] 是 truthy */ }
if ({}){ /* 会进来:{} 是 truthy */ }

ToNumber:常见转换结果

Number("") === 0;
Number(" ") === 0;
Number("1") === 1;
Number("1a") // NaN
Number(null) === 0;
Number(undefined) // NaN

补充:+xNumber(x) 的常见短写(面试能提一嘴即可)。


+ 的双重语义:拼接 vs 加法

1 + 2; // 3
"1" + 2; // "12"
1 + "2"; // "12"
1 + 2 + "3"; // "33"(先算 1+2,再拼接)
"1" + 2 + 3; // "123"(从左到右)

工程建议:字符串拼接尽量用模板字符串,数字运算尽量确保两边都是 number。


==(宽松相等)核心规则(面试用得上的)

只背最常见、最能解释行为的规则:

  1. null == undefinedtrue,且它们只和彼此相等。
  2. == 遇到对象会先 ToPrimitive(对象先变原始值再比)。
  3. ==string/booleannumber 比较时,通常会转成 number 再比。
null == undefined; // true
null == 0; // false
false == 0; // true(false -> 0)
"0" == 0; // true("0" -> 0)
[] == 0; // true([] -> "" -> 0)
[] == ""; // true([] -> "")

结论:面试能把“对象先 ToPrimitive”说清楚,一般就够了。


典型题 & 标准答法

Q1:为什么推荐 ===

  • === 不做隐式类型转换,可预测性更强。
  • == 的隐式转换规则复杂,易产生“看似诡异”的边界行为。

Q2:什么时候 == 是合理的?

if (x == null) {
// 同时覆盖 null 和 undefined
}

这是最常见、也是最“可控”的 == 使用场景。


易错点/坑

  • if (obj) 不代表对象“非空”,只代表它不是 falsy({}[] 都会为真)。
  • Number(null) === 0 很反直觉,面试可能追问。
  • [] == 0 这类题要从 ToPrimitive 解释,别死背答案。

速记要点(可背诵)

  • 转换顺序:对象先 ToPrimitive,再按上下文 ToNumber/ToString/ToBoolean。
  • === 默认首选;x == null 是少数可接受的宽松判断。