如何使用 ES6 中的 WeakMap 对象

如何使用 ES6 中的 WeakMap 对象

简介

ES6 中的 WeakMap 是一种新的数据结构,类似于 Map,但它只接受对象作为键,并且键是弱引用的,这意味着当这个对象没有其他引用时,垃圾回收器会自动回收它。WeakMap 也是一个无序的集合,但是与 Map 不同,WeakMap 的键不可枚举。

使用场景

WeakMap 擅长处理一些与对象有关的场景,例如在一个对象中存储一些私密数据,减少内存泄漏,同时避免全局变量污染等等。

以下是几个常见的使用场景:

  1. 私有变量

在 JavaScript 中,我们无法创建真正的私有变量,但是使用 WeakMap 可以模拟私有变量。我们可以将一个对象作为 WeakMap 的键,将私有变量存储在这个对象中,由于这个对象是弱引用的,只要不再引用这个对象,垃圾回收器就会自动回收这个对象和存储在其中的私有变量。

示例代码:

const privateData = new WeakMap();

class MyClass { constructor(firstName, lastName) { privateData.set(this, { firstName, lastName }); }

getFullName() { const { firstName, lastName } = privateData.get(this); return ${firstName} ${lastName}; } }

const myInstance = new MyClass("John", "Doe"); console.log(myInstance.getFullName()); // "John Doe" console.log(privateData.has(myInstance)); // true myInstance = null; // myInstance 不再引用 MyClass 实例,垃圾回收器会自动回收它

  1. 减少内存泄漏

在 JavaScript 中,闭包经常会导致内存泄漏。当某个函数被引用时,它的外部变量也会一直存在于内存中,无法被回收。

可以使用 WeakMap 来解决这个问题,将外部变量作为 WeakMap 的键,将函数作为值存储在 WeakMap 中,这样只要函数没有其他引用,垃圾回收器就会自动回收这个函数和存储在 WeakMap 中的键。

示例代码:

const callbackMap = new WeakMap();

function addEventListener(eventName, callback) { const callbacks = callbackMap.get(eventName) || []; callbackMap.set(eventName, [...callbacks, callback]); }

function removeEventListener(eventName, callback) { const callbacks = callbackMap.get(eventName); if (!callbacks) { return; } callbackMap.set(eventName, callbacks.filter(cb => cb !== callback)); }

function fireEvent(eventName, ...args) { const callbacks = callbackMap.get(eventName) || []; for (const callback of callbacks) { callback.apply(null, args); } }

addEventListener("click", function() { console.log("clicked"); });

fireEvent("click"); // "clicked"

  1. 避免全局变量污染

在 JavaScript 中,全局变量很容易被其它代码所污染。使用 WeakMap 可以将一些全局变量存储在一个对象中,这个对象作为 WeakMap 的键,避免全局变量污染。

示例代码:

const globalData = new WeakMap(); globalData.set({}, { username: "John", password: "123456" });

console.log(globalData.has({})); // false console.log(globalData.get({})); // undefined

const globalObject = {}; globalData.set(globalObject, { username: "Jane", password: "654321" });

console.log(globalData.has(globalObject)); // true console.log(globalData.get(globalObject)); // { username: "Jane", password: "654321" }

总结

ES6 中的 WeakMap 可以在一些与对象有关的场景中发挥作用,它可以模拟私有变量,减少内存泄漏,避免全局变量污染等等。但需要注意的是,WeakMap 的键是弱引用的,如果没有其他引用,垃圾回收器会自动回收它,因此需要谨慎使用。

参考

[1] https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/WeakMap

[2] https://blog.csdn.net/chenxin6677849/article/details/104448065

[3] https://www.cnblogs.com/joyff/p/10338944.html

来源:JavaScript中文网 ,转载请注明来源 本文地址:https://www.javascriptcn.com/post/65403ccb7d4982a6eb9bcdaa


纠错
反馈