为什么new Map也被垃圾回收了?
javascript中,如下代码,为何在car1=null之后,carMap.get(car1)的结果是undefined?我觉得应该依然是Corolla,因为如果是WeakMap的话,那应该是undefined,但实际是new Map(),依然会触发垃圾回收吗?为什么?
let carMap = new Map();
let car1 = { brand: 'Toyota' };
let car2 = { brand: 'Honda' };
carMap.set(car1, 'Corolla');
carMap.set(car2, 'Civic');
console.log(carMap.get(car1)); // 输出: Corolla 正常
console.log(carMap.get(car2)); // 输出: Civic 正常
car1 = null;
console.log(carMap.get(car1)); // 问题点:为什么会输出undefined?
console.log(carMap.get(car2)); // 输出: Civic 正常
回复
1个回答

test
2024-06-19
并不是GC的问题,而是楼上说的 carMap.get(null)
的问题。你期望的是 car1
变更为了 null
那么我给 carMap
的设置的 key
也会变成 null
?但其实并不会。这点可以从简单的代码例子中看到:
let carMap = new Map();
let car1 = { brand: 'Toyota' };
let car2 = { brand: 'Honda' };
carMap.set(car1, 'Corolla');
carMap.set(car2, 'Civic');
carMap.get(car1);
// Corolla
carMap.get(car2);
// Civic
car1 = null;
carMap
// Map { {…} → "Corolla", {…} → "Civic" }
// size: 2
// <entries>
// 0: Object { brand: "Toyota" } → "Corolla"
// 1: Object { brand: "Honda" } → "Civic"
所以你在使用 carMap.get(car1)
时并不会获得期望的 Corolla
输出。
这部分就和你给对象的操作有关系了。当你将一个新的对象赋值给 car1
这个变量,那么变量 car1
将指向新对象的内存地址。而不是原来的内存地址了。
如果你要修改 car1
这个变量的值而不去修改这个变量的指向,那么你应该操作变量 car1
,而不是直接给变量 car1
赋值一个新的值 👇
let carMap = new Map();
let car1 = { brand: 'Toyota' };
let car2 = { brand: 'Honda' };
carMap.set(car1, 'Corolla');
carMap.set(car2, 'Civic');
carMap.get(car1);
// Corolla
carMap.get(car2);
// Civic
car1.value = 'test';
carMap.get(car1);
// Corolla
补充一个简易的Demo来说明赋值操作的区别:
let obj1 = { name: 'John' };
let obj2 = obj1;
obj2.name = 'Jane'; // 这将修改 obj1 的 name 属性
console.log(obj1.name); // 输出 'Jane'
obj2 = { name: 'Bob' }; // 这将不会修改 obj1,因为 obj2 现在指向一个新的对象
console.log(obj1.name); // 输出 'Jane'
相关阅读
javascript - Using Array objects as key for ES6 Map - Stack Overflow24.1.3.6 Map.prototype.get (key) | ECMAScript® 2025 Language SpecificationObject.is() - JavaScript | MDN
回复

适合作为回答的
- 经过验证的有效解决办法
- 自己的经验指引,对解决问题有帮助
- 遵循 Markdown 语法排版,代码语义正确
不该作为回答的
- 询问内容细节或回复楼层
- 与题目无关的内容
- “赞”“顶”“同问”“看手册”“解决了没”等毫无意义的内容