如何使用 ES6 中的 WeakMap 对象
简介
ES6 中的 WeakMap 是一种新的数据结构,类似于 Map,但它只接受对象作为键,并且键是弱引用的,这意味着当这个对象没有其他引用时,垃圾回收器会自动回收它。WeakMap 也是一个无序的集合,但是与 Map 不同,WeakMap 的键不可枚举。
使用场景
WeakMap 擅长处理一些与对象有关的场景,例如在一个对象中存储一些私密数据,减少内存泄漏,同时避免全局变量污染等等。
以下是几个常见的使用场景:
- 私有变量
在 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 实例,垃圾回收器会自动回收它
- 减少内存泄漏
在 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"
- 避免全局变量污染
在 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