javascript中对象比较只看内存地址而非内容,===、==和object.is()均如此;即使内容相同,不同对象实例地址不同则结果为false;深比较需手动或借助工具实现。

JavaScript 中用 ===、== 或 Object.is() 比较两个对象时,判断的不是“长得一不一样”,而是“是不是同一个东西”——也就是它们在内存里是不是指向同一块地址。
引用地址相等就是“同一个实例”
对象是引用类型,变量存的不是数据本身,而是一个指向堆内存中实际数据的“地址”。就像两本房产证写的是同一套房子的地址,那它们指的就是同一处房产。
- 如果
obj1 = {a: 1},obj2 = obj1,那么obj1 === obj2是 true —— 因为它们共享一个地址 - 如果
obj1 = {a: 1},obj2 = {a: 1},哪怕内容一模一样,obj1 === obj2仍是 false —— 它们各自在内存里新开了一块地
为什么不能靠 === 判断“内容是否一样”
因为 === 不看属性、不看值、不递归检查嵌套结构,它只做一件事:比对两个变量底层存储的内存地址是否完全相同。
-
{x: 1} === {x: 1}→ false(两个独立对象) -
const a = {x: 1}; const b = a; a === b→ true(b 只是 a 的别名) -
Object.is({x: 1}, {x: 1})→ false(和 === 行为一致,仍比地址)
常见误判场景:隐式转换也不救得了对象
即使使用 ==,对象比较依然绕不开地址。它最多在一边是原始值时尝试转换,但两边都是对象时,== 和 === 行为完全一致。
-
[] == []→ false(空数组也是对象,地址不同) -
[1] == "1"→ true(右边是字符串,左边数组被转成字符串 "1") -
{a:1} == {a:1}→ false(纯对象之间不触发有意义的转换)
想比内容?得自己动手或借助工具
要判断“两个对象键值是否完全相同”,必须显式遍历属性,逐个对比,还要处理:undefined 与缺失属性的区别、NaN 的特殊性、循环引用、嵌套对象/数组等问题。
- 简单扁平对象:可用
JSON.stringify(obj1) === JSON.stringify(obj2)(仅限可序列化、无函数/undefined/Date 等) - 通用方案:用 Lodash 的
_.isEqual(),或手写深比较函数(递归 + 类型判断 + key 数量校验) - 现代替代:部分场景可用
structuredClone配合浅比较,但仍有兼容性和性能限制
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











