类型转换(隐式/显式)怎么解释?== 的规则是啥?
面试速答(30 秒版 TL;DR)
- JS 类型转换本质是三步:ToPrimitive(先变原始值) → ToNumber/ToString/ToBoolean(按上下文转换)。
+既可能做数字加法也可能做字符串拼接:只要有一边是字符串或能被转成字符串参与拼接,就走拼接。==会做隐式转换(宽松相等),规则很多且容易踩坑;工程上默认用===,只有在明确需要“null或undefined”同判时才用x == null。
心智模型:转换是“上下文驱动”
你需要能说清:为什么同一个值在不同位置表现不一样。
- 条件判断(
if (x))触发 ToBoolean - 数学运算(
- * / % < >等)触发 ToNumber - 字符串拼接(
+且一侧是字符串倾向)触发 ToString - 对象参与比较/运算会先 ToPrimitive(调用
valueOf/toString或Symbol.toPrimitive)
ToBoolean:哪些是假值(falsy)?
只有这 7 个是假值,其余都是真值(truthy):
false0、-00n""(空字符串)nullundefinedNaN
if ([]){ /* 会进来:[] 是 truthy */ }
if ({}){ /* 会进来:{} 是 truthy */ }
ToNumber:常见转换结果
Number("") === 0;
Number(" ") === 0;
Number("1") === 1;
Number("1a") // NaN
Number(null) === 0;
Number(undefined) // NaN
补充:+x 是 Number(x) 的常见短写(面试能提一嘴即可)。
+ 的双重语义:拼接 vs 加法
1 + 2; // 3
"1" + 2; // "12"
1 + "2"; // "12"
1 + 2 + "3"; // "33"(先算 1+2,再拼接)
"1" + 2 + 3; // "123"(从左到右)
工程建议:字符串拼接尽量用模板字符串,数字运算尽量确保两边都是 number。
==(宽松相等)核心规则(面试用得上的)
只背最常见、最能解释行为的规则:
null == undefined为true,且它们只和彼此相等。==遇到对象会先 ToPrimitive(对象先变原始值再比)。==在string/boolean与number比较时,通常会转成 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是少数可接受的宽松判断。