ECMAScript 7 中的 WeakMap 和 WeakSet
在现代的 JavaScript 开发中,对象和集合为数据组织和处理提供了方便和效率。在 ES6 和之前的版本中,关于对象的讨论主要集中在 Map 和 Set 上,但是在 ECMAScript 7 中,WeakMap 和 WeakSet 这两种数据结构也被加入了标准库中。
WeakMap 和 WeakSet 的特点
首先,我们需要了解 WeakMap 和 WeakSet 与 Map 和 Set 的不同:
WeakMap 和 WeakSet 的 key 必须是对象,而 Map 和 Set 的 key 可以是任何类型的值。
WeakMap 和 WeakSet 的 value 也可以是任何类型的值。
WeakMap 和 WeakSet 的 key 是弱引用,不会阻止被垃圾回收机制回收,而 Map 和 Set 会保留对 key 的引用。
WeakMap 和 WeakSet 不支持迭代方法,因为其内部的 key 集合可能会在任何时候发生变化。
这些特点使得 WeakMap 和 WeakSet 在某些情况下比 Map 和 Set 更适合使用。
WeakMap 的使用场景
WeakMap 的主要用途是存储对象相关的元数据,而这些元数据可能会被垃圾回收机制回收。例如,你可以使用一个 WeakMap 存储对象的私有属性,而不必担心这些私有属性会阻止对象被回收。
以下是一个简单的 WeakMap 使用示例:
let wm = new WeakMap(); let key = {}; wm.set(key, "hello"); console.log(wm.get(key)); // "hello" key = null; // 此时,key 所指的对象被垃圾回收机制回收,并且 WeakMap 中对应的 entry 也被清除了
在上面的示例中,我们使用一个 WeakMap 存储了一个对象的字符串属性。然后,我们将 key 设置为 null,这会导致该对象被垃圾回收机制回收并从 WeakMap 中移除。
WeakSet 的使用场景
WeakSet 的主要用途是存储对象集合,而这些对象只可以出现一次,因为 WeakSet 中的 key 是独一无二的。例如,你可以使用一个 WeakSet 存储用户对象,以确保每个用户只在集合中出现一次。
以下是一个简单的 WeakSet 使用示例:
let ws = new WeakSet(); let user1 = { name: "Alice" }; let user2 = { name: "Bob" }; let user3 = { name: "Charlie" }; ws.add(user1); ws.add(user2); ws.add(user3); console.log(ws.has(user1)); // true console.log(ws.has(user2)); // true console.log(ws.has(user3)); // true ws.add(user1); console.log(ws.has(user1)); // true user1 = null; // 此时,原来的 user1 对象被垃圾回收机制回收,并且 WeakSet 中对应的 entry 也被清除了
在上面的示例中,我们创建了一个 WeakSet,并向其中添加了三个对象。我们还向 WeakSet 中添加了两次 user1,但是,这并不会导致 WeakSet 中包含多个 user1。最后,我们将 user1 设置为 null,这会导致该对象被垃圾回收机制回收并从 WeakSet 中移除。
总结
WeakMap 和 WeakSet 是 ECMAScript 7 引入的两个新数据结构,它们比 Map 和 Set 更加适合用于存储对象相关的元数据以及对象集合。WeakMap 和 WeakSet 都具有 key 弱引用的特点,这使得它们不会阻止其存储的对象被垃圾回收机制回收。使用 WeakMap 和 WeakSet 需要慎重,但是,当你需要存储对象相关的元数据以及对象集合时,它们会变得非常有用。
来源:JavaScript中文网 ,转载请注明来源 本文地址:https://www.javascriptcn.com/post/65b4e419add4f0e0ffdbdcae