JavaScript 的 ==、=== 和 Object.is 有什么区别?隐式类型转换怎么判断?
下面是一段教学用的模拟面试。
🧑💻 面试官:== 和 === 有什么区别?
🙋♂️ 我:== 会转换类型,=== 不转换。
🧑💻 面试官:那 null == 0 是不是 true?它们不都能跟“空”联系起来吗?
🙋♂️ 我:不是,宽松相等有具体规则,不能随意猜。
🧑💻 面试官:Object.is 又比 === 多了什么?两个内容相同的对象,它能判断相等吗?
相等不是“看起来差不多”。先确认「使用哪套比较规则」,对象身份和字段内容也要分开。
面试速答(60 秒版)
=== 是严格相等,不先转换两个操作数的类型。类型不同通常就不相等;对象则比较是否为同一个对象,不逐个比较字段。
== 是宽松相等。类型不同时,会按语言规定处理,例如字符串和数字比较时可能转换字符串,布尔值会转成数字。null 和 undefined 有专门规则,不能概括成“先统一转数字”。
Object.is 和严格相等大部分情况一致,但认为 NaN 与 NaN 相同,同时区分 +0 和 -0。它也不是对象深比较。
普通业务代码优先使用明确的类型和严格比较。外部输入需要转换时,先把转换和校验写清楚,不让 == 顺手决定业务含义。

知识点详解:不要用一句“会转换”猜所有结果
先看 ===,把不需要转换的部分记牢
数字 1 和字符串 “1”,使用 === 是 false。两个空对象各自创建,即使字段相同,仍不是同一个对象,因此也不相等。
如果两个变量引用同一个对象,=== 则是 true。这个判断关注身份,不是内容。
数字中还有两个值得记住的边界:NaN === NaN 是 false;+0 === -0 是 true。这是明确规则,不是引擎偶尔的计算误差。
== 不是把所有值转成同一种类型
字符串和数字比较时,例如 “1” == 1,结果是 true。布尔值参与时,例如 false == 0,也可以得到 true。
但 null 和 undefined 之间有特殊的宽松相等关系。null == undefined 是 true,null == 0 却是 false。不要因为 Number(null) 等于 0,就把这个结果直接搬给 ==。
比较普通对象与基本值时,还可能涉及对象转基本值。例如空数组与数字比较会走相应转换,得到一些容易误解的结果。这些规则可以解释,但没必要把文章写成怪表达式竞赛。
下面这些输入足以检查你有没有掌握主要边界:
| 比较 | 结果 | 主要原因 |
|---|---|---|
| “1” == 1 | true | 字符串与数字的转换规则 |
| “1” === 1 | false | 类型不同 |
| null == undefined | true | 特殊宽松相等规则 |
| null == 0 | false | 不能随意套 Number(null) |
| NaN === NaN | false | 严格相等的数字规则 |
| +0 === -0 | true | 严格相等不区分这两个零 |
Object.is 并不是“更严格的 ===”
Object.is(NaN, NaN) 是 true,Object.is(+0, -0) 是 false。
所以说它“更严格”,容易让读者以为它只是拒绝更多情况。实际上,两种规则在不同边界上给出不同答案。
两个独立创建的对象,Object.is 仍然返回 false。它不会打开对象,帮你遍历里面的 name 和 age。MDN 的比较说明还区分了 SameValueZero:某些集合操作用它,不能把所有 API 都统一成 Object.is。

输入本来混乱,换运算符也不会自动整理
假设查询参数中 limit 是字符串 “10”,内部默认值是数字 10。更好的做法是在接口边界解析、检查是否为允许的整数,再把规范化后的值交给业务。
如果直接使用 ==,代码虽然可能得到想要的结果,但“允许空字符串吗”“允许小数吗”“超过范围怎么办”都没有被回答。
因此,优先 === 并不意味着永远拒绝转换,而是让转换发生在明确的位置,规则可以测试。
本题是在比较 JavaScript 的语言语义,没有通用实现算法需要翻译;Python 的 ==、is 不能冒充这三个 API 的对应版本。
面试官继续追问
React 的依赖比较为什么会提到 Object.is?
React 某些依赖比较使用 Object.is 的语义,因此新的对象引用即使内容相同,也可能被认为变化。要分析具体 API,不是认为 React 会自动深比较所有依赖。
== 一定不能用吗?
不是。比如有意使用 value == null 同时判断 null 和 undefined,可以表达一个明确规则。但要让团队知道这里的意图,不用它掩盖未知输入。
Set 里放两次 NaN,会出现两个成员吗?
不会因此成为两个不同成员。Set 的相等判断使用 SameValueZero,它认为 NaN 相同,也不区分正负零。不同 API 的比较契约要分别确认。
面试速记卡
- ===:不先转换类型;对象看身份,不看字段内容。
- ==:按具体规则转换,null 与 undefined 有特殊关系。
- Object.is:NaN 相同,正负零不同,不是深比较。
- 集合 API:可能使用 SameValueZero,不能一律套 Object.is。
- 业务输入:先明确转换与校验,再做比较。
公司面试真题
这道题暂未收录可核验的公司真题来源。你可以先阅读本文解析,或浏览已收录的公司面试真题。
浏览公司面试真题 →