JavaScript中Map存储对象引用的行为是否属于官方语言标准?
问题结论
你观察到的运行行为是ECMAScript标准明确规定的强制行为,所有兼容ES2015(ES6)及更高版本的JavaScript实现都会严格遵循该规则,不存在版本差异或实现差异。
原理说明
这个现象本质上是JavaScript的基础核心规则,和Map.set方法本身没有特殊绑定:
- JavaScript中所有对象类型的赋值、传参、存储操作默认都是引用传递,不会自动生成对象副本
- 调用
map1.set('bar', foo2)时,存入Map的不是foo2指向的实例对象的拷贝,而是该对象的内存引用地址 - 后续你通过原变量
foo2修改对象属性时,修改的是同一块内存地址上的对象值,因此从Map中取出该引用访问属性时,自然会读取到修改后的值
补充说明
Map.set文档没有单独提及该逻辑,是因为这属于JavaScript对象的通用规则,不需要数据结构重复说明。你看到的Map.get文档的相关描述,已经完整覆盖了Map存储对象的逻辑:Map全程只存储对象引用,不会隐式执行对象拷贝,存(set)和取(get)操作对应的是同一个对象的引用,逻辑完全自洽。
如果需要存储对象的快照、切断和原对象的关联,可以手动对对象做深拷贝后再存入Map,示例如下:
const map1 = new Map(); let foo = function() { this.test = 1; } let foo2 = new foo(); // 手动深拷贝后存入Map map1.set('bar', JSON.parse(JSON.stringify(foo2))); foo2.test = 2; console.log(map1.get('bar').test); // 此时输出1,和原对象修改无关
内容的提问来源于stack exchange,提问作者cr001
相关产品推荐
相关产品推荐

