Javascript 为什么map.has()为已删除对象返回false?
Javascript 为什么map.has()为已删除对象返回false?,javascript,Javascript,让john={name:“john”}; 设map=newmap(); map.set(john,“…”); 设weakmap=newweakmap(); weakmap.set(john,“…”); console.log(map.has(john));//真的 console.log(weakmap.has(john));//真的 john=null; console.log(map.has(john));//假线A console.log(weakmap.has(john));//虚线B
让john={name:“john”};
设map=newmap();
map.set(john,“…”);
设weakmap=newweakmap();
weakmap.set(john,“…”);
console.log(map.has(john));//真的
console.log(weakmap.has(john));//真的
john=null;
console.log(map.has(john));//假线A
console.log(weakmap.has(john));//虚线B
console.log(map);//映射{{…}→ “…”}行C
console.log(weakmap);//弱映射{{…}→ “…”}D行
通过键入john=null
您将用指向null
的新指针替换旧指针,并且您不能再访问以前的john
以将其用作映射的键,因此您观察到的情况完全正常。Map
的键是john
的值,而不是变量的名称
john
的上一个值未被垃圾收集,因为仍然从Map
引用,并且您仍然可以使用以下选项之一检索它:
通过键入john=null
您将用指向null
的新指针替换旧指针,并且您无法再访问以前的john
以将其用作映射的键,因此您观察到的情况完全正常。Map
的键是john
的值,而不是变量的名称
john
的上一个值未被垃圾收集,因为仍然从Map
引用,并且您仍然可以使用以下选项之一检索它:
john=null
不会删除以前由john
引用的对象,它将变量john
设置为指向null
,而不是它以前指向的对象
当您运行console.log(map.has(john))
,现在john
设置为null
,这相当于运行console.log(map.has(null))代码>。映射没有由null
键入的条目,因此它返回false
我知道即使垃圾收集器删除了一个对象,这个对象也可以在地图中使用
这是不正确的。垃圾回收器不会删除仍有强引用指向它的对象。即使您将john
设置为null
,删除对对象的引用,您的映射仍然有一个指向它的键,因此垃圾收集器不会将其从内存中释放出来。如果您只有WeakMap,那么它可能在垃圾回收器下次运行时被垃圾回收,但这不会很快发生,您无法在同一代码块中观察到它。john=null
不会删除以前由john
引用的对象,它将变量john
设置为指向null
,而不是它以前指向的对象
当您运行console.log(map.has(john))
,现在john
设置为null
,这相当于运行console.log(map.has(null))代码>。映射没有由null
键入的条目,因此它返回false
我知道即使垃圾收集器删除了一个对象,这个对象也可以在地图中使用
这是不正确的。垃圾回收器不会删除仍有强引用指向它的对象。即使您将john
设置为null
,删除对对象的引用,您的映射仍然有一个指向它的键,因此垃圾收集器不会将其从内存中释放出来。如果您只有弱映射,那么它可能会在垃圾收集器下一步运行时被垃圾收集—但这不会很快发生,您无法在同一代码块中观察到它。看起来您想要演示常规映射和弱映射之间的区别。但它不起作用的原因很简单:
您无法检测对象是否是通过JavaScript代码进行垃圾收集的,因为这会使您仍然需要检查引用。但是如果你有一个引用,那么它不可能被垃圾收集
关于你的问题:
我知道即使垃圾收集器删除了一个对象,这个对象也可以在地图中使用
事实并非如此。如果它位于常规映射中,则构成对对象的引用,因此不能对其进行垃圾收集
所以我希望在“行A”上输出“true”,但它打印false我缺少什么
没有办法编写JavaScript代码来为映射打印true
,为弱映射打印false
。您的测试有缺陷,因为您将john
更改为其他对象,因此您的.has(john)
调用与原始对象无关,而是与您给此变量的新值有关。因此,这些结果与您存储在地图中的原始对象无关
为什么我在C行和D行看到john object?如果A行和B行的结果为假,为什么C行和D行打印john对象
因为false
输出不是关于原始john对象,而是关于null
还要意识到,console在向您显示WeakMap的内容方面帮了您一个大忙,就像这样,而在JavaScript代码中,您无法迭代WeakMap的所有内容。看起来您想要演示常规映射和弱映射之间的区别。但它不起作用的原因很简单:
您无法检测对象是否是通过JavaScript代码进行垃圾收集的,因为这会使您仍然需要检查引用。但是,如果你有一个推荐人,那么这是不可能的