JavaScript中==会触发隐式类型转换而===不会;==按抽象相等算法转换类型后比较,===要求类型和值均相同;推荐用===以避免隐蔽bug,仅val == null可作为检查null/undefined的安全简写。

JavaScript 中的类型转换主要分两种:显式转换(你主动调用 Number()、String()、Boolean() 等)和隐式转换(运算符或比较时自动发生)。而 == 和 === 的核心区别就在于是否触发隐式类型转换——== 会,=== 不会。
== 的隐式转换规则(抽象相等比较)
当使用 == 比较两个值时,如果类型不同,JS 引擎会按固定步骤尝试转换其中一方(或双方),再比较。这个过程由“抽象相等算法”定义,关键逻辑如下:
- 如果任一操作数是
null或undefined,仅当两者同为null或同为undefined时返回true;null == undefined是true,但它们都不等于其他任何值(包括0、false、空字符串) - 如果一个是字符串,另一个是数字,把字符串转成数字再比较(例如
"123" == 123→123 == 123→true) - 如果一个是布尔值,先转成数字:
false → 0,true → 1(所以true == 1为true,false == 0也为true) - 如果一个是对象(含数组、函数、Date 等),另一个是原始值(字符串/数字/布尔),先把对象调用
valueOf(),若结果不是原始值,再调用toString(),直到得到原始值再继续比较(例如[0] == false→[0].toString() → "0"→"0" == false→"0" == 0→0 == 0→true) - 对象与对象比较,不转换,只比引用(即是否指向同一内存地址)
=== 的行为(严格相等)
=== 完全跳过类型转换。它要求:类型相同 且 值相等。只要类型不同,直接返回 false。
-
0 === false→false(number vs boolean) -
"1" === 1→false(string vs number) -
null === undefined→false(类型不同) -
NaN === NaN→false(这是唯一一个自己不等于自己的情况,===也不例外) -
0 === -0→true(ES6 规定二者类型值均相同)
几个容易踩坑的 == 表达式
这些看似反直觉的结果,其实都严格遵循上面的转换规则:
立即学习“Java免费学习笔记(深入)”;
-
[] == false→true:空数组toString()得"",再转数字为0,0 == false→true -
[0] == false→true:如前所述,[0].toString() → "0"→Number("0") → 0→0 == false -
{} == true→false:对象先valueOf()(返回自身,非原始值),再toString()→"[object Object]",转数字为NaN,NaN == true→NaN == 1→false -
"0" == false→true:字符串转数字得0,0 == false
为什么推荐用 === 而不是 ==
因为 == 的转换逻辑复杂、隐蔽,依赖上下文,容易导致意外行为和难以调试的 bug。现代代码规范(如 ESLint 的 eqeqeq 规则)默认禁止 ==,除非明确需要宽松比较(比如检查 null || undefined,可用 val == null 作为简写)。
- 用
===可预测、可读性高、性能略优(省去转换开销) - 需要类型转换时,显式写出更清晰:比如
Number(str) === 42或String(num) === "42" - 判断是否为
null或undefined,val == null是安全且被广泛接受的简写(等价于val === null || val === undefined)











