JavaScript中对象用==或===比较永远返回false,因比较的是内存地址而非内容;浅比较需手动遍历自有属性;深比较需递归处理嵌套及特殊类型,推荐使用Lodash的_.isEqual。

JavaScript 中直接用 == 或 === 比较两个对象,**永远返回 false**,哪怕它们的属性和值一模一样。这是因为对象是引用类型,比较的是内存地址,不是内容。
为什么 obj1 === obj2 不管用
两个对象即使结构完全相同,只要不是同一个引用(即不是同一个内存地址),就判为不等:
const a = { name: 'Alice', age: 25 };
const b = { name: 'Alice', age: 25 };
console.log(a === b); // false —— 它们是两个独立对象
console.log(a === a); // true —— 同一个引用
浅比较:适合简单、一层结构的对象
手动遍历 key,逐个比对属性值(注意要排除原型链上的属性):
当用户要求为 Java 代码添加注释、修改注释、审查注释、整理注释格式,或要求按照代码注释规范处理 Java 文件时,使用本技能。本技能用于统一生成和维护 Java 类注释模板、按 Git 对比 release 判断版本号、补充每行代码上方中文块注释、调整注释空行规则,并保持 Java 文件 UTF-8 无 BOM 编码。典型触发场景包括:补充类注释、更新 @version、检查 @author 来源、整理行尾注释、把注释放到代码上一行、检查注释是否符合规范、构建前检查 Java 注释风格。
- 先检查是否都是对象且非
null - 再确保键的数量一致
- 然后对每个自有属性,用
===比较值(仅适用于基本类型或单层对象)
function shallowEqual(obj1, obj2) {
if (obj1 === obj2) return true;
if (typeof obj1 !== 'object' || obj1 === null ||
typeof obj2 !== 'object' || obj2 === null) return false;
const keys1 = Object.keys(obj1);
const keys2 = Object.keys(obj2);
if (keys1.length !== keys2.length) return false;
for (let key of keys1) {
if (!keys2.includes(key) || obj1[key] !== obj2[key]) {
return false;
}
}
return true;
}
深比较:处理嵌套对象和数组
递归比较每一层属性,需特别处理:null、Array、Date、RegExp 等特殊类型。实际项目中建议用成熟库:
-
Lodash:用
_.isEqual(obj1, obj2),健壮、支持循环引用、覆盖各种边界情况 - fast-deep-equal:轻量、高性能,适合只做纯深比较的场景
- 自己实现需谨慎:容易漏掉
NaN === NaN是false,或陷入无限递归(对象互相引用)
其他实用方式
根据场景选择更高效或语义更清晰的方法:
- JSON.stringify()(慎用):仅适用于纯数据对象(无函数、undefined、Symbol、Date、BigInt、循环引用)且属性顺序一致
-
Object.is():比
===更严格(如Object.is(NaN, NaN) === true),但仍是引用比较,不解决深比较问题 -
自定义唯一标识:如果对象有业务主键(如
id),直接比obj1.id === obj2.id更准确、更快
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










