JavaScript中WeakMap与WeakSet深度解析及实用技巧

 更新时间:2026年06月16日 09:32:50   作者:兆子龙  
WeakSet还可以用于实现简单的缓存机制,尤其是当你不希望缓存条目永远存在于内存中时,这篇文章主要介绍了JavaScript中WeakMap与WeakSet深度解析及实用技巧的相关资料,需要的朋友可以参考下

一、Map/Set 的内存问题

普通的 Map 和 Set 会阻止垃圾回收。

let user = { name: 'Alice' };
const map = new Map();
map.set(user, 'metadata');

user = null;  // 想释放 user
// 但 map 仍然持有引用,user 不会被回收

WeakMap 和 WeakSet 使用弱引用,不会阻止垃圾回收。

二、WeakMap 基础

特点

  • 键必须是对象
  • 键是弱引用
  • 不可遍历
  • 没有 size 属性
const wm = new WeakMap();

let obj = { name: 'Alice' };
wm.set(obj, 'metadata');

console.log(wm.get(obj));  // 'metadata'

obj = null;  // obj 可以被垃圾回收
// wm 中的条目也会自动删除

API

const wm = new WeakMap();

wm.set(key, value);  // 设置
wm.get(key);  // 获取
wm.has(key);  // 检查
wm.delete(key);  // 删除

三、WeakMap 实战应用

应用 1:私有属性

const privateData = new WeakMap();

class Person {
  constructor(name, age) {
    privateData.set(this, { name, age });
  }
  
  getName() {
    return privateData.get(this).name;
  }
  
  getAge() {
    return privateData.get(this).age;
  }
}

const person = new Person('Alice', 25);
console.log(person.getName());  // 'Alice'
console.log(person.name);  // undefined(无法直接访问)

应用 2:DOM 节点缓存

const cache = new WeakMap();

function processElement(element) {
  if (cache.has(element)) {
    return cache.get(element);
  }
  
  const result = expensiveOperation(element);
  cache.set(element, result);
  return result;
}

// 当 DOM 节点被移除时,缓存自动清理

应用 3:对象元数据

const metadata = new WeakMap();

function addMetadata(obj, data) {
  metadata.set(obj, data);
}

function getMetadata(obj) {
  return metadata.get(obj);
}

const user = { name: 'Alice' };
addMetadata(user, { createdAt: Date.now(), role: 'admin' });

四、WeakSet 基础

特点

  • 值必须是对象
  • 值是弱引用
  • 不可遍历
  • 没有 size 属性
const ws = new WeakSet();

let obj = { name: 'Alice' };
ws.add(obj);

console.log(ws.has(obj));  // true

obj = null;  // obj 可以被垃圾回收

API

const ws = new WeakSet();

ws.add(value);  // 添加
ws.has(value);  // 检查
ws.delete(value);  // 删除

五、WeakSet 实战应用

应用 1:标记对象

const disabledElements = new WeakSet();

function disableElement(element) {
  disabledElements.add(element);
  element.setAttribute('disabled', true);
}

function isDisabled(element) {
  return disabledElements.has(element);
}

应用 2:防止循环引用

function traverse(obj, visited = new WeakSet()) {
  if (visited.has(obj)) {
    return;  // 已访问过,避免死循环
  }
  
  visited.add(obj);
  
  for (const key in obj) {
    if (typeof obj[key] === 'object') {
      traverse(obj[key], visited);
    }
  }
}

六、与 Map/Set 对比

特性Map/SetWeakMap/WeakSet
键/值类型任意只能是对象
垃圾回收阻止不阻止
可遍历
size
使用场景通用集合内存敏感场景

七、实用技巧

技巧 1:实现观察者模式

const observers = new WeakMap();

function observe(target, callback) {
  if (!observers.has(target)) {
    observers.set(target, new Set());
  }
  observers.get(target).add(callback);
}

function notify(target, data) {
  const callbacks = observers.get(target);
  if (callbacks) {
    callbacks.forEach(cb => cb(data));
  }
}

技巧 2:记忆化函数

const memoCache = new WeakMap();

function memoize(fn) {
  return function(obj) {
    if (memoCache.has(obj)) {
      return memoCache.get(obj);
    }
    const result = fn(obj);
    memoCache.set(obj, result);
    return result;
  };
}

总结 

到此这篇关于JavaScript中WeakMap与WeakSet的文章就介绍到这了,更多相关JS WeakMap与WeakSet内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • 浅谈webpack对样式的处理

    浅谈webpack对样式的处理

    这篇文章主要介绍了浅谈webpack对样式的处理,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2018-01-01
  • 实现高性能javascript的注意事项

    实现高性能javascript的注意事项

    JavaScript代码在web应用程序中经常用到,但是很多开发者忽视了一些性能方面的知识,如何编写高性能javascript代码呢?接下来,小编跟大家一起学习
    2019-05-05
  • javascript日期比较方法实例分析

    javascript日期比较方法实例分析

    这篇文章主要介绍了javascript日期比较方法,列举了3个实例形式分析了javascript针对日期与时间的相关操作技巧,具有一定参考借鉴价值,需要的朋友可以参考下
    2016-06-06
  • bootstarp modal框居中显示的实现代码

    bootstarp modal框居中显示的实现代码

    这篇文章主要介绍了bootstarp modal框居中显示的实现代码,需要的朋友可以参考下
    2017-02-02
  • 完美解决JS文件页面加载时的阻塞问题

    完美解决JS文件页面加载时的阻塞问题

    下面小编就为大家带来一篇完美解决JS文件页面加载时的阻塞问题。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2016-12-12
  • 创建、调用JavaScript对象的方法集锦

    创建、调用JavaScript对象的方法集锦

    这篇文章主要介绍了创建、调用JavaScript对象的方法集锦,需要的朋友可以参考下
    2014-12-12
  • 精通Javascript系列之数值计算

    精通Javascript系列之数值计算

    在JS中如果希望某个变量包含一个数值,那么无需限定其必须是整数或者是浮点数,下面来个例子
    2011-06-06
  • JS设置cookie、读取cookie

    JS设置cookie、读取cookie

    js设置cookie有很多种方法,包括JS设置cookie、读取cookie,工作中常会用到!下面是详细代码,感兴趣的小伙伴们可以参考一下
    2016-02-02
  • JavaScript中valueOf函数与toString方法深入理解

    JavaScript中valueOf函数与toString方法深入理解

    基本上,所有JS数据类型都拥有valueOf和toString这两个方法,null除外。它们俩解决javascript值运算与显示的问题,本文将详细介绍,有需要的朋友可以参考下
    2012-12-12
  • 微信小程序:数据存储、传值、取值详解

    微信小程序:数据存储、传值、取值详解

    这篇文章主要介绍了微信小程序:数据存储、传值、取值,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2019-05-05

最新评论