javascript中用===或==比较两个不同对象时只比较内存地址(引用),不比较内容;即使结构、属性、值完全相同,只要不是同一实例,结果均为false;深度相等需手动实现或借助_.isequal等工具。

JavaScript 中用 === 或 == 比较两个不同对象时,**只比较内存地址(引用),不比较内容**。即使两个对象结构、属性、值完全一样,只要不是同一个对象实例,结果就是 false。
引用比较的本质是地址比对
对象在 JavaScript 中是引用类型,变量存储的是指向堆内存中对象的引用(类似指针)。比较时引擎只检查这两个引用是否指向同一块内存地址。
-
{a: 1} === {a: 1}→ false(两个独立对象,地址不同) -
const obj1 = {a: 1}; const obj2 = obj1; obj1 === obj2→ true(共享同一引用) -
[] === []→ false(两个空数组也是不同实例)
== 和 === 在对象比较中行为一致
对两个对象使用 == 时,不会触发类型转换或“隐式展开”,它和 === 一样,仅做引用相等判断。也就是说:
-
{x: 1} == {x: 1}和{x: 1} === {x: 1}都返回 false - 只有当两边是同一个对象(或同一数组、函数等)时,两者才都为 true
想比较对象内容?得手动深比较
若需判断两个对象“长得一样”,必须自己实现或借助工具进行**深度比较(deep equality)**:
- 简单场景可用
JSON.stringify(a) === JSON.stringify(b)(但有局限:忽略函数、undefined、Symbol;顺序敏感;不能处理循环引用) - 生产环境推荐用成熟库,如 Lodash 的
_.isEqual(a, b),它能正确处理嵌套、类型、NaN、日期、正则等 - 自己写递归比较需注意:处理 null/undefined、类型校验、遍历键名一致性、递归子属性、避免循环引用死循环
常见误解与陷阱
容易误以为某些操作会“自动深比较”,其实不会:
-
Array.prototype.includes()或indexOf()查找对象时,仍用引用比较 →[{id:1}].includes({id:1})是 false -
Set或Map的键去重也基于引用 →new Set([{a:1}, {a:1}]).size是 2 - React 中
useMemo或React.memo的依赖项或 props 比较,同样只看引用 —— 内容相同但新建对象会导致不必要更新
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











