javascript隐式类型转换严格按抽象操作执行:加法+优先字符串拼接,==依规则链式转换,布尔上下文仅6个falsy值,对象转原始值依赖valueof/tostring或symbol.toprimitive。

JavaScript 中的隐式类型转换不是“随意变”,而是按规范严格走抽象操作(如 ToPrimitive、ToNumber、ToString)一步步降级执行的。它不改变原值,只在特定运算上下文中临时生成新值参与计算,因此同一变量在不同位置可能被转成不同类型,从而导致看似矛盾的结果。
加法运算 +:拼接优先,数字退让
只要有一个操作数是字符串,+ 就放弃数学加法,全部转成字符串再拼接:
-
1 + "2"→"12"(数字1被ToString) -
true + "hello"→"truehello"(true→"true") -
[] + ""→""(空数组toString()得空字符串) -
[1, 2] + "3"→"1,23"(数组先toString()成"1,2",再拼接)
注意:1 + [] 是 "1",不是 1;而 1 - [] 却是 1——因为 - 强制走 ToNumber 路线。
相等判断 ==:多层转换,路径依赖
== 不是简单“转一边”,而是按决策树规则匹配类型,常见链式转换:
-
0 == false→ 先把falseToNumber得0,再0 == 0→true -
"0" == false→"0"ToNumber得0,falseToNumber得0→true -
[] == false→ 空数组ToPrimitive(先valueOf()失败,再toString()得""),""ToNumber得0,false也得0→true -
null == undefined是唯一特例,直接返回true,不走任何转换
这种嵌套转换让结果极难直觉预测,所以生产环境一律推荐用 ===。
布尔上下文:真假判断只看“falsy 列表”
在 if、&&、||、三元表达式中,JS 调用 ToBoolean,仅以下六个值为 falsy:
-
false、0、-0、0n(BigInt 零)、""(空字符串)、null、undefined、NaN
其余全是 truthy,包括:"0"、"false"、[]、{}、new Boolean(false)。这意味着:
-
if ([]) { ... }会执行(空数组是 truthy) -
0 || "default"返回"default",但"0" || "default"返回"0"
对象转原始值:valueOf 和 toString 的博弈
当对象参与需要原始值的运算(如 ==、+、==)时,引擎按 hint 调用 [Symbol.toPrimitive](hint);若未定义,则依次尝试 valueOf() 和 toString(),取第一个返回原始值的方法结果:
-
{} + []→ 实际是[object Object]+""→"[object Object]" -
+[1, 2]→ 数组toString()得"1,2",再ToNumber("1,2")→NaN - 可自定义:让
const a = { [Symbol.toPrimitive](hint) { return hint === 'number' ? 1 : 'a'; } };,则a == 1和a == "a"都可为true
这个机制正是实现 “a == 1 && a == 2 && a == 3” 成立的关键基础——靠每次取值时动态返回不同原始值。











