JS WeakMap 詳細(xì)用法從基礎(chǔ)到實(shí)戰(zhàn)指南
WeakMap 是 JavaScript 中的一個(gè)集合類型,它類似于普通的 Map,但有幾個(gè)關(guān)鍵的不同之處:
- 鍵的限制:
WeakMap的鍵必須是對(duì)象,而不能是原始值(如字符串、數(shù)字等)。 - 內(nèi)存管理:當(dāng)鍵對(duì)象不再被引用時(shí),
WeakMap會(huì)自動(dòng)將其從集合中刪除,這有助于垃圾回收機(jī)制回收內(nèi)存。 - 不可枚舉:
WeakMap中的鍵是不可以被枚舉的。
WeakMap 是 ES6 新增的弱引用鍵值對(duì)集合,核心特點(diǎn):
- 鍵必須是對(duì)象(不能是原始值:字符串 / 數(shù)字 / 布爾等)
- 鍵是弱引用:鍵對(duì)象沒有其他引用時(shí),會(huì)被垃圾回收自動(dòng)清理(不造成內(nèi)存泄漏)
- 不可枚舉(沒有
keys()/values()/forEach(),也不能用for...of) - 只有核心方法:
set()/get()/has()/delete()
一、基礎(chǔ)用法(完整示例)
// 1. 創(chuàng)建 WeakMap
const wm = new WeakMap();
// 2. 定義對(duì)象作為鍵(原始值不能做鍵)
let user = { name: "張三" };
let info = { age: 20 };
// 3. set(key, value):添加鍵值對(duì)
wm.set(user, "用戶信息");
wm.set(info, { id: 1001 });
// 4. get(key):獲取值
console.log(wm.get(user)); // 輸出:用戶信息
// 5. has(key):判斷是否存在
console.log(wm.has(info)); // 輸出:true
// 6. delete(key):刪除鍵值對(duì)
wm.delete(info);
console.log(wm.has(info)); // 輸出:false錯(cuò)誤用法(鍵不能是原始值)
// 報(bào)錯(cuò):Invalid value used as weak map key
wm.set("字符串鍵", 123);
wm.set(123, "數(shù)值鍵");二、核心特性:弱引用(最重要?。?/h2>
WeakMap 的鍵是弱引用,如果鍵對(duì)象不再被其他變量引用,垃圾回收機(jī)制會(huì)自動(dòng)回收該對(duì)象,并從 WeakMap 中移除,不會(huì)造成內(nèi)存泄漏。
對(duì)比:Map 會(huì)造成內(nèi)存泄漏,WeakMap 不會(huì)
// 1. 使用 Map(強(qiáng)引用)
let obj = { id: 1 };
const map = new Map();
map.set(obj, "數(shù)據(jù)");
obj = null; // 手動(dòng)釋放引用
// Map 中依然保留 obj,不會(huì)被回收 → 內(nèi)存泄漏
// 2. 使用 WeakMap(弱引用)
let obj2 = { id: 2 };
const weakMap = new WeakMap();
weakMap.set(obj2, "數(shù)據(jù)");
obj2 = null; // 手動(dòng)釋放引用
// 沒有其他引用 → 垃圾回收自動(dòng)清理 obj2 和 weakMap 中的鍵值對(duì)三、最常用實(shí)戰(zhàn)場景
場景 1:給 DOM 元素附加數(shù)據(jù)(無內(nèi)存泄漏)
操作 DOM 時(shí),用 WeakMap 存儲(chǔ)關(guān)聯(lián)數(shù)據(jù),DOM 被刪除后數(shù)據(jù)自動(dòng)回收:
const btn = document.querySelector("#btn");
const domData = new WeakMap();
// 給 DOM 綁定數(shù)據(jù)
domData.set(btn, { clickCount: 0 });
// 使用數(shù)據(jù)
btn.addEventListener("click", () => {
const data = domData.get(btn);
data.clickCount++;
console.log(data.clickCount);
});
// DOM 被刪除時(shí) → WeakMap 自動(dòng)清理,無內(nèi)存泄漏
// btn.remove();場景 2:私有屬性(模擬類的私有數(shù)據(jù))
利用 WeakMap 實(shí)現(xiàn)真正私有(外部無法訪問,不會(huì)被遍歷):
const _private = new WeakMap();
class User {
constructor(name) {
// 私有數(shù)據(jù)存在 WeakMap 中
_private.set(this, { name });
}
getName() {
return _private.get(this).name;
}
}
const u = new User("李四");
console.log(u.getName()); // 李四
console.log(u.name); // undefined(真正私有)場景 3:緩存對(duì)象關(guān)聯(lián)數(shù)據(jù)
const cache = new WeakMap();
// 緩存計(jì)算結(jié)果
function getCachedData(obj) {
if (cache.has(obj)) {
return cache.get(obj);
}
// 模擬耗時(shí)計(jì)算
const result = obj.id * 100;
cache.set(obj, result);
return result;
}四、WeakMap 可用方法匯總
| 方法 | 作用 |
|---|---|
wm.set(keyObj, value) | 添加 / 更新鍵值對(duì) |
wm.get(keyObj) | 獲取對(duì)應(yīng)值 |
wm.has(keyObj) | 判斷是否存在,返回布爾值 |
wm.delete(keyObj) | 刪除指定鍵值對(duì) |
wm.clear() | 已廢棄,不要使用 |
五、WeakMap vs Map(關(guān)鍵區(qū)別)
| 特性 | WeakMap | Map |
|---|---|---|
| 鍵類型 | 只能是對(duì)象 | 任意類型(對(duì)象 / 字符串 / 數(shù)字等) |
| 引用類型 | 弱引用(自動(dòng)垃圾回收) | 強(qiáng)引用(不會(huì)自動(dòng)回收) |
| 內(nèi)存泄漏 | 不會(huì) | 可能會(huì) |
| 枚舉 | 不可枚舉(無迭代) | 可枚舉(keys/values/entries) |
| 大小 | 無 size 屬性 | 有 size |
總結(jié)
- 什么時(shí)候用 WeakMap:
- 給對(duì)象附加額外數(shù)據(jù)
- DOM 元素關(guān)聯(lián)數(shù)據(jù)
- 類私有屬性
- 不想造成內(nèi)存泄漏的緩存
- 記住核心:鍵必須是對(duì)象 + 弱引用自動(dòng)回收 + 不可枚舉
- 它是專門為避免對(duì)象關(guān)聯(lián)數(shù)據(jù)造成內(nèi)存泄漏設(shè)計(jì)的 API
到此這篇關(guān)于JS WeakMap 詳細(xì)用法:從基礎(chǔ)到實(shí)戰(zhàn)的文章就介紹到這了,更多相關(guān)js weakmap用法內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
- JavaScript中WeakSet和WeakMap的用法詳解
- JavaScript集合Map與WeakMap使用最佳實(shí)踐
- 詳解JavaScript中的Map和WeakMap
- 深入探究JavaScript中WeakMap的原理與用法
- 一文詳解JS中的Map、Set、WeakMap和WeakSet
- JS中Map、WeakMap和Object的區(qū)別解析
- JavaScript?WeakMap的具體使用
- javascript中Set、Map、WeakSet、WeakMap區(qū)別
- JavaScript WeakMap使用詳解
- JavaScript中Object、map、weakmap的區(qū)別分析
相關(guān)文章
從JavaScript純函數(shù)解析最深刻的函子 Monad實(shí)例
這篇文章主要為大家介紹了從JavaScript純函數(shù)解析最深刻的函子 Monad實(shí)例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-10-10
JavaScript函數(shù)調(diào)用經(jīng)典實(shí)例代碼
JavaScript提供了4種函數(shù)調(diào)用,一般形式的函數(shù)調(diào)用、作為對(duì)象的方法調(diào)用、使用 call 和 apply 動(dòng)態(tài)調(diào)用、使用 new 間接調(diào)用,下面這篇文章主要給大家介紹了關(guān)于JavaScript函數(shù)調(diào)用的相關(guān)資料,需要的朋友可以參考下2021-12-12
js實(shí)現(xiàn)遮罩層劃出效果是生成div而不是顯示
單純的遮蓋層劃出是比較簡單的,而本例介紹的這個(gè)就有點(diǎn)難度,生成div,而不是顯示存在的div,需要的朋友可以參考下2014-07-07
JS采用絕對(duì)定位實(shí)現(xiàn)回到頂部效果完整實(shí)例
這篇文章主要介紹了JS采用絕對(duì)定位實(shí)現(xiàn)回到頂部效果,以完整實(shí)例形式分析了JS定位到頁面頂部功能的實(shí)現(xiàn)方法,涉及javascript動(dòng)態(tài)操作頁面元素與屬性的相關(guān)技巧,需要的朋友可以參考下2016-06-06
Javascript的并行運(yùn)算實(shí)現(xiàn)代碼
隨著多核cpu的普級(jí),并發(fā)/并行多線程運(yùn)算在主流的編程語言越來越流行,而在目前Javascript實(shí)現(xiàn)中還看不到在語言方面支持多線程,現(xiàn)在Javascript如此流行,真希望今后會(huì)在語言的層面有很大的變化.2010-11-11
three.js如何實(shí)現(xiàn)3D動(dòng)態(tài)文字效果
這篇文章主要給大家介紹了關(guān)于three.js如何實(shí)現(xiàn)3D動(dòng)態(tài)文字效果的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2021-03-03
正則表達(dá)式判斷是否存在中文和全角字符和判斷包含中文字符串長度
對(duì)于一些更安全的容錯(cuò)嚴(yán)重,需要用到2008-09-09
webpack是如何實(shí)現(xiàn)模塊化加載的方法
這篇文章主要介紹了webpack是如何實(shí)現(xiàn)模塊化加載的方法,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2019-11-11

