在 ES11 中,我们可以使用 WeakMap 和 WeakSet 这两个新的数据类型。它们的作用类似于 Map 和 Set,但是它们的特点使得它们在某些场景下更加适用。
WeakMap
与 Map 不同,WeakMap 中的键必须是对象,并且这些对象是弱引用,即如果这些对象在程序的其他地方都没有被引用,则在垃圾回收时,它们就可以被回收。这也是 WeakMap 名称中包含“Weak”的来由。
我们可以使用 WeakMap 来存储一些对象的私有属性,如下所示:
// javascriptcn.com 代码示例 const wm = new WeakMap(); class MyClass { constructor() { wm.set(this, { privateProp: "secret" }); } getPrivateProp() { return wm.get(this).privateProp; } setPrivateProp(value) { wm.get(this).privateProp = value; } } let obj = new MyClass(); obj.getPrivateProp(); // "secret" obj.setPrivateProp("new secret"); obj.getPrivateProp(); // "new secret"
在这个例子中,我们使用 WeakMap 存储 MyClass 类的实例的私有属性,并通过 getPrivateProp 和 setPrivateProp 方法来访问和修改私有属性。
当 MyClass 的实例被垃圾回收时,与之关联的私有属性也会被回收。
WeakSet
与 Set 类似,WeakSet 中存储的是对象的弱引用。当这些对象在程序中没有被引用时,它们也可以被垃圾回收。
WeakSet 常用于存储一些对象的集合,如下所示:
// javascriptcn.com 代码示例 const ws = new WeakSet(); let obj1 = {}; let obj2 = {}; ws.add(obj1); ws.add(obj2); ws.has(obj1); // true ws.has(obj2); // true obj1 = null; ws.has(obj1); // false,因为 obj1 已经被垃圾回收
在这个例子中,我们使用 WeakSet 存储了两个对象,当这些对象被回收时,它们也会从 WeakSet 中自动删除。
总结
WeakMap 和 WeakSet 的使用场景主要在于需要存储一些对象引用,并且这些引用并不需要被程序的其他部分所使用。当这些对象没有被引用时,它们也会被回收,避免内存泄漏的发生。
需要注意的是,WeakMap 和 WeakSet 都是弱引用,并不是所有场景下都适用。例如当需要持有一些对象的强引用时,应该使用 Map 和 Set。
掌握了 WeakMap 和 WeakSet 的用法,我们可以更加灵活地使用对象在程序中的引用,有效地管理内存的使用。
参考代码
// javascriptcn.com 代码示例 const wm = new WeakMap(); class MyClass { constructor() { wm.set(this, { privateProp: "secret" }); } getPrivateProp() { return wm.get(this).privateProp; } setPrivateProp(value) { wm.get(this).privateProp = value; } } let obj = new MyClass(); obj.getPrivateProp(); // "secret" obj.setPrivateProp("new secret"); obj.getPrivateProp(); // "new secret" const ws = new WeakSet(); let obj1 = {}; let obj2 = {}; ws.add(obj1); ws.add(obj2); ws.has(obj1); // true ws.has(obj2); // true obj1 = null; ws.has(obj1); // false,因为 obj1 已经被回收
来源:JavaScript中文网 ,转载请注明来源 本文地址:https://www.javascriptcn.com/post/654c9d197d4982a6eb60fe48