在 ECMAScript 2016 中,引入了 WeakMap 和 WeakSet 两个新的数据结构。它们是 Map 和 Set 的变体,但与它们不同的是,它们的键和值都必须是对象,并且在没有其他引用时,它们会自动从内存中删除。这使得它们非常适合存储临时数据,例如缓存或临时状态。
WeakMap
WeakMap 是一种映射,其中键必须是对象,而值可以是任何类型。与普通的 Map 不同,WeakMap 中的键是弱引用,这意味着当键没有其他引用时,它们会自动从 WeakMap 中删除。这使得 WeakMap 非常适合存储临时数据,例如缓存或临时状态。
用法
创建一个 WeakMap 很简单,只需要使用 new
关键字和一个可选的初始值:
const cache = new WeakMap();
然后,您可以使用 set
方法将键值对添加到 WeakMap 中:
const key = {}; const value = 'my value'; cache.set(key, value);
您可以使用 get
方法从 WeakMap 中检索值:
console.log(cache.get(key)); // 'my value'
您还可以使用 has
方法检查 WeakMap 中是否存在键:
console.log(cache.has(key)); // true
最后,您可以使用 delete
方法从 WeakMap 中删除键值对:
cache.delete(key);
实现
WeakMap 的实现非常简单,因为它只是一个将键映射到值的对象,但使用弱引用。在 JavaScript 中,弱引用通常通过将键存储为对象的属性并使用 null
值来删除属性来实现。这种方法的缺点是,如果您没有显式地将键设置为 null
,则它们将永远存在于对象中。
WeakMap 解决了这个问题,它使用 WeakRef
对象作为键,并将值存储在私有的 Map
对象中。当键被垃圾回收时,它们将自动从 Map
中删除。这意味着您不必担心手动将键设置为 null
,因为它们会自动从 WeakMap 中删除。
WeakSet
WeakSet 是一种集合,其中所有元素都必须是对象。与普通的 Set 不同,WeakSet 中的元素是弱引用,这意味着当元素没有其他引用时,它们会自动从 WeakSet 中删除。这使得 WeakSet 非常适合存储临时数据,例如缓存或临时状态。
用法
创建一个 WeakSet 很简单,只需要使用 new
关键字和一个可选的初始值:
const cache = new WeakSet();
然后,您可以使用 add
方法将元素添加到 WeakSet 中:
const obj = {}; cache.add(obj);
您可以使用 has
方法检查 WeakSet 中是否存在元素:
console.log(cache.has(obj)); // true
最后,您可以使用 delete
方法从 WeakSet 中删除元素:
cache.delete(obj);
实现
WeakSet 的实现与 WeakMap 类似,它只是一个存储对象的集合,但使用弱引用。在 JavaScript 中,弱引用通常通过将对象存储在数组或对象中,并使用 null
值来删除它们来实现。这种方法的缺点是,如果您没有显式地将元素设置为 null
,则它们将永远存在于数组或对象中。
WeakSet 解决了这个问题,它使用 WeakRef
对象作为元素,并将它们存储在私有的 Set
对象中。当元素被垃圾回收时,它们将自动从 Set
中删除。这意味着您不必担心手动将元素设置为 null
,因为它们会自动从 WeakSet 中删除。
总结
在 ECMAScript 2016 中,WeakMap 和 WeakSet 提供了一种存储临时数据的新方法。它们都使用弱引用,这意味着当键或元素没有其他引用时,它们会自动从内存中删除。这使得它们非常适合存储临时数据,例如缓存或临时状态。虽然 WeakMap 和 WeakSet 的使用方法非常简单,但它们的实现却涉及到一些复杂的概念,例如垃圾回收和弱引用。了解这些概念将有助于您更好地理解 WeakMap 和 WeakSet 的工作原理,从而更好地使用它们。
来源:JavaScript中文网 ,转载请注明来源 https://www.javascriptcn.com/post/65d1d2a4add4f0e0ffa6ca4f