WeakMap 和 Map 的比较

lxf2023-05-22 01:29:22

主要区别

WeakMap 和 Map 主要有两点区别。WeakMap 只能接受对象做键名,而 Map 的键名可以是任意值。WeakMap 的键名所指向的对象,不计入垃圾回收机制。也就是说,WeakMap 键名所对象的对象未来可能会消失,这个可以防止内存泄露。

let wm = new WeakMap();
wm.set({ foo: true }, 1);
wm.set("34", 4); // TypeError: Invalid value used as weak map key

从上面的例子可以看出,新生成的 WeakMap 实例,键名只能是对象,不能使用其他类型的值。

WeakMap 的键名弱引用的特点很难演示,因为很难观察它的自动消失。不过,可以通过借助 process.memoryUsage 方法查看内存占用情况来判断引用是否自动被清除。

WeakMap 和 Map 的比较

上面的例子中,--expose-gc 表示允许手动执行垃圾回收机制。在实际的运行代码中,可以通过 global.gc() 来执行垃圾回收,通过 process.memoryUsage() 来查看内存占用情况。可以看到,实际运行过程中,每个例子都执行了三次手动垃圾回收来查看内存的占用情况,分别是创建实例前,给实例增加数据后,手动清除数据。WeakMap 的实例和 Map 的实例最大的区别在于清除里面引用后的内存情况,WeakMap 的实例清除里面的引用后内存回到了初始状态,而 Map 的实例清除里面的引用后内存空间还是被占用。

语法上的区别

由于 WeakMap 的键名是否存在无法确定,跟垃圾回收机制是否运行有关,这使得 WeakMap 缺少了很多类似 Map 的方法。一是没有遍历操作,包括 keys(),values(),entries(),forEach(),也没有 size 属性。二是没有清空方法 clear()。

let wm = new WeakMap();
wm.set({ foo: true }, 1);
// console.log(wm.keys()); // TypeError: wm.keys is not a function
// console.log(wm.values()); // TypeError: wm.values is not a function
// console.log(wm.entries()); // TypeError: wm.entries is not a function
// console.log(wm.forEach()); // TypeError: wm.forEach is not a function
console.log(wm.size); // undefined
console.log(wm.clear()); // TypeError: wm.clear is not a function

从上面的例子可以看到,新生成的 WeakMap 对象没有 keys(),values(),entries(),forEach(),clear(),使用 size 属性的时候都是返回 undefined。

小结

本文首先提到了 WeakMap 和 Map 的两点区别,WeakMap 的键名只能是对象且键名指向的对象不计入垃圾回收机制;接着提到了语法上的区别,WeakMap 没有 keys(),values(),entries(),forEach(),clear() 和 size 属性。WeakMap 适用于键名所指向的对象会消失的情况,可以防止内存泄露。

参考资料:es6.ruanyifeng.com/#docs/set-m…

本网站是一个以CSS、JavaScript、Vue、HTML为核心的前端开发技术网站。我们致力于为广大前端开发者提供专业、全面、实用的前端开发知识和技术支持。 在本网站中,您可以学习到最新的前端开发技术,了解前端开发的最新趋势和最佳实践。我们提供丰富的教程和案例,让您可以快速掌握前端开发的核心技术和流程。 本网站还提供一系列实用的工具和插件,帮助您更加高效地进行前端开发工作。我们提供的工具和插件都经过精心设计和优化,可以帮助您节省时间和精力,提升开发效率。 除此之外,本网站还拥有一个活跃的社区,您可以在社区中与其他前端开发者交流技术、分享经验、解决问题。我们相信,社区的力量可以帮助您更好地成长和进步。 在本网站中,您可以找到您需要的一切前端开发资源,让您成为一名更加优秀的前端开发者。欢迎您加入我们的大家庭,一起探索前端开发的无限可能!