Weakmap的详细解释是什么?

2026-04-28 11:222阅读0评论SEO资讯
  • 内容介绍
  • 文章标签
  • 相关推荐

本文共计1151个文字,预计阅读时间需要5分钟。

Weakmap的详细解释是什么?

首先,我们来看一个例子:

javascriptlet obj={ name: 'toto' }; // { name: 'toto' }// 这个对象可以被读取到,因为obj这个变量对其有引用// 将引用覆盖掉 obj=null; // 这个对象将不会被内存回收,因为还存在其他引用// 将引用覆盖掉后,这个对象将被从内存中移除

这个例子中,对象`obj`可以被读取到,因为变量`obj`对其有引用。当我们将`obj`赋值为`null`时,这个对象将不会被立即从内存中移除,因为可能还存在其他引用指向它。只有当所有引用都被移除后,对象才会被垃圾回收机制回收。

先看一个例子

let obj = { name: 'toto' } // { name: 'toto' }这个对象能够被读取到,因为obj这个变量名有对它的引用 // 将引用覆盖掉 obj = null // 这个对象将会被从内存中移除,因为我们已经失去了对它所有的引用

再来看另外一个例子

let obj = { name: 'toto' } let arr = [ obj ] obj = null

在这个例子中,对象{name:'toto'}不会被从内存中移除,因为数组arr保存了对它的引用 强引用和弱引用之间有什么区别呢?

事实上,javascript中的大多数变量都保存着对一个对象的强引用。比如上面这个数组保存着对对象{name:'toto'}的强引用

如果一个变量保存着对一个对象的强引用,那么这个对象将不会被垃圾回收,但是如果一个变量只保存着对这个对象的弱引用,那么这个对象将会被垃圾回收

一些变量类型在对象上有一个弱引用,这就是Weakmap的情况

Weakmap

weakmap是一个额外的数据存储,它可以让我们从外部(第三方库)扩展或者封装一个对象,而不需要进行垃圾回收的推断,或者能够智能的创建一个缓存函数。

不用担心看不明白,在比较mapweakmap之前我将解释并展示它的含义。

Map和Weakmap的比较

使用map,对象会占用内存,可能不会被垃圾回收。Map对一个对象是强引用

let obj = { name: 'toto' } let mapObj = new Map() mapObj.set(obj, 'any value') obj = null mapObj.size() // 1

Weakmap则是完全不同的,它不会阻止关键对象的垃圾回收

第一条规则,weakmap只接受object作为key,第二条规则是它只保存对对象的弱引用。

let obj = { name: 'toto' } let weakmapObj = new WeakMap() weakmapObj.set(obj, 'any value') obj = null weakmapObj .size() // 0

对象被垃圾回收器删除,因为weakmap在对象{ name: ‘toto’ }上只有弱引用,而这个对象已经没有强引用了。(只有变量obj有保持引用)

何时使用Weakmap?

正如你所看到的,Weakmap可以用在任何地方

缓存器函数

const cache = new WeakMap() const process = function (obj) { // 如果输入的值不在缓存器中 if (!cache.has(obj)) { // 想象一个函数需要很大的内存或者资源 // 当输入相同时,我们不想重复执行bigOperation函数 const result = bigOperation(obj) // 所以此时执行一次函数并将它的结果存入缓存中 cache.set(obj, result) } return cache.get(obj) } let obj = { /* any object */ } // 第一次我们没有这个输入作为缓存,所以在第二次的时候我们才不需要执行这个函数, const firstResult = process(obj) // 只需要从缓存中取出结果 const secondeResult = process(obj) // 源对象将被从weakmap中移除 obj = null

使用map,这个缓存器函数应该将obj对象保存在内存中。

但这将导致内存泄漏!

当我们对一个不再使用的对象保持引用的时候将会造成内存泄漏,所以如果你不再使用对象,请删除它的任何变量引用。

Weakmap的详细解释是什么?

使用weakmap时我们不应该使用.keys() / .values() /.entries(),因为我们不知道何时垃圾回收器会移除这个对象。

最后一个例子

动态无泄漏内存的访问计数器

// 访问计数器 let visitsCountMap = new WeakMap() // 增加访问计数 function countUser(user) { const count = visitsCountMap.get(user) || 0 visitsCountMap.set(user, count + 1) } let toto = { name: "toto" } countUser(toto) // 计算访问次数 // 将toto对象从内存中移除 toto = null

本文共计1151个文字,预计阅读时间需要5分钟。

Weakmap的详细解释是什么?

首先,我们来看一个例子:

javascriptlet obj={ name: 'toto' }; // { name: 'toto' }// 这个对象可以被读取到,因为obj这个变量对其有引用// 将引用覆盖掉 obj=null; // 这个对象将不会被内存回收,因为还存在其他引用// 将引用覆盖掉后,这个对象将被从内存中移除

这个例子中,对象`obj`可以被读取到,因为变量`obj`对其有引用。当我们将`obj`赋值为`null`时,这个对象将不会被立即从内存中移除,因为可能还存在其他引用指向它。只有当所有引用都被移除后,对象才会被垃圾回收机制回收。

先看一个例子

let obj = { name: 'toto' } // { name: 'toto' }这个对象能够被读取到,因为obj这个变量名有对它的引用 // 将引用覆盖掉 obj = null // 这个对象将会被从内存中移除,因为我们已经失去了对它所有的引用

再来看另外一个例子

let obj = { name: 'toto' } let arr = [ obj ] obj = null

在这个例子中,对象{name:'toto'}不会被从内存中移除,因为数组arr保存了对它的引用 强引用和弱引用之间有什么区别呢?

事实上,javascript中的大多数变量都保存着对一个对象的强引用。比如上面这个数组保存着对对象{name:'toto'}的强引用

如果一个变量保存着对一个对象的强引用,那么这个对象将不会被垃圾回收,但是如果一个变量只保存着对这个对象的弱引用,那么这个对象将会被垃圾回收

一些变量类型在对象上有一个弱引用,这就是Weakmap的情况

Weakmap

weakmap是一个额外的数据存储,它可以让我们从外部(第三方库)扩展或者封装一个对象,而不需要进行垃圾回收的推断,或者能够智能的创建一个缓存函数。

不用担心看不明白,在比较mapweakmap之前我将解释并展示它的含义。

Map和Weakmap的比较

使用map,对象会占用内存,可能不会被垃圾回收。Map对一个对象是强引用

let obj = { name: 'toto' } let mapObj = new Map() mapObj.set(obj, 'any value') obj = null mapObj.size() // 1

Weakmap则是完全不同的,它不会阻止关键对象的垃圾回收

第一条规则,weakmap只接受object作为key,第二条规则是它只保存对对象的弱引用。

let obj = { name: 'toto' } let weakmapObj = new WeakMap() weakmapObj.set(obj, 'any value') obj = null weakmapObj .size() // 0

对象被垃圾回收器删除,因为weakmap在对象{ name: ‘toto’ }上只有弱引用,而这个对象已经没有强引用了。(只有变量obj有保持引用)

何时使用Weakmap?

正如你所看到的,Weakmap可以用在任何地方

缓存器函数

const cache = new WeakMap() const process = function (obj) { // 如果输入的值不在缓存器中 if (!cache.has(obj)) { // 想象一个函数需要很大的内存或者资源 // 当输入相同时,我们不想重复执行bigOperation函数 const result = bigOperation(obj) // 所以此时执行一次函数并将它的结果存入缓存中 cache.set(obj, result) } return cache.get(obj) } let obj = { /* any object */ } // 第一次我们没有这个输入作为缓存,所以在第二次的时候我们才不需要执行这个函数, const firstResult = process(obj) // 只需要从缓存中取出结果 const secondeResult = process(obj) // 源对象将被从weakmap中移除 obj = null

使用map,这个缓存器函数应该将obj对象保存在内存中。

但这将导致内存泄漏!

当我们对一个不再使用的对象保持引用的时候将会造成内存泄漏,所以如果你不再使用对象,请删除它的任何变量引用。

Weakmap的详细解释是什么?

使用weakmap时我们不应该使用.keys() / .values() /.entries(),因为我们不知道何时垃圾回收器会移除这个对象。

最后一个例子

动态无泄漏内存的访问计数器

// 访问计数器 let visitsCountMap = new WeakMap() // 增加访问计数 function countUser(user) { const count = visitsCountMap.get(user) || 0 visitsCountMap.set(user, count + 1) } let toto = { name: "toto" } countUser(toto) // 计算访问次数 // 将toto对象从内存中移除 toto = null