Object.is不比较物理内存地址,而是判断值或引用是否严格相等;对对象字面量总返回false,因每次创建都生成新引用,与===行为一致。

Object.is 不能测试物理内存地址的异同,它比较的是值(value)或引用(reference)的相等性,而非对象在内存中的物理位置。JavaScript 是一门不暴露底层内存地址的语言,开发者无法通过任何标准 API(包括 Object.is、=== 或 ==)直接获取或比对两个对象的“物理内存地址”。
为什么 Object.is 对对象字面量总是返回 false
当你写:
const a = { x: 1 };
const b = { x: 1 }; // 即使内容完全相同,也是新分配的对象
console.log(Object.is(a, b)); // false
这是因为 a 和 b 是两个独立分配在堆内存中的对象,它们的引用(即内部指针)指向不同地址。Object.is(a, b) 等价于 a === b,只判断是否为同一引用,不深入比较属性或内存布局。
拷贝后的对象必然产生新内存分配
无论使用哪种拷贝方式,只要结果是“新对象”,它就一定位于新的内存位置:
-
浅拷贝(如
{...obj}、Object.assign({}, obj)):创建新对象,复制顶层属性值;若含引用类型,其内部引用仍指向原内存地址,但外层对象本身是新的。 -
深拷贝(如
structuredClone(obj)、第三方库):递归创建所有嵌套对象的新实例,整个结构都位于新分配的内存区域。
因此,拷贝前后的两个对象,Object.is 必然返回 false —— 这反映的是“非同一对象”,不是“内存地址差异报告”。
有没有办法间接推测“是否共享内存”?
虽然无法读取真实地址,但可通过可观察行为推断引用关系:
- 修改一个对象的某个引用属性(如数组、嵌套对象),看另一个是否同步变化 → 若变化,说明该属性仍共享内存(浅拷贝未切断引用)。
- 用
Object.is(obj1.prop, obj2.prop)检查特定属性是否为同一引用 → 可判断该字段是否被真正拷贝。 - 对不可变值(如数字、字符串、Symbol)用
Object.is是可靠的,因为它们没有“内存地址”概念,只看值是否严格相等。
小结:别用 Object.is 判断内存位置
Object.is 的设计目标是提供比 === 更严格的相等语义(例如 Object.is(NaN, NaN) === true),但它仍是引用/值比较工具。JavaScript 中不存在标准方法获取对象的物理内存地址,也不鼓励按此思路编程。关注逻辑相等性(用 lodash.isEqual)、引用一致性(用 === 或 Object.is),或可变状态的副作用表现,才是实际开发中的正确路径。

















