高階指南之 WeakMap
「WeakMap
」 對象是一組鍵/值對的集合,其中的鍵是弱引用的。其鍵必須是對象,而值能夠是任意的。web
在 JavaScript 裏,map API 能夠經過使其四個 API 方法共用兩個數組(一個存放鍵,一個存放值)來實現。給這種 map 設置值時會同時將鍵和值添加到這兩個數組的末尾。從而使得鍵和值的索引在兩個數組中相對應。當從該 map 取值的時候,須要遍歷全部的鍵,而後使用索引從存儲值的數組中檢索出相應的值。算法
但這樣的實現會有兩個很大的缺點,首先賦值和搜索操做都是 O(n) 的時間複雜度( n 是鍵值對的個數),由於這兩個操做都須要遍歷所有整個數組來進行匹配。另一個缺點是可能會致使內存泄漏,由於數組會一直引用着每一個鍵和值。這種引用使得垃圾回收算法不能回收處理他們,即便沒有其餘任何引用存在了。數組
相比之下,原生的 WeakMap 持有的是每一個鍵對象的「弱引用」,這意味着在沒有其餘引用存在時垃圾回收能正確進行。原生 WeakMap 的結構是特殊且有效的,其用於映射的 key 只有在其沒有被回收時纔是有效的。微信
正因爲這樣的弱引用,WeakMap
的 key 是不可枚舉的 (沒有方法能給出全部的 key)。若是key 是可枚舉的話,其列表將會受垃圾回收機制的影響,從而獲得不肯定的結果。所以,若是你想要這種類型對象的 key 值的列表,你應該使用 Map
。編輯器
基本上,若是你要往對象上添加數據,又不想幹擾垃圾回收機制,就可使用 WeakMap。函數
屬性
WeakMap.length
length
屬性的值爲 0。flex
WeakMap.protorype
WeakMap 構造器的原型。容許添加屬性到全部的 WeakMap 對象。this
方法
WeakMap.prototype.delete(key)
移除key的關聯對象。執行後 WeakMap.prototype.has(key)返回``false。
url
WeakMap.prototype.get(key)
返回key關聯對象
, 或者 undefined
(沒有key關聯對象時)。spa
WeakMap.prototype.has(key)
根據是否有key關聯對象返回一個Boolean值。
WeakMap.prototype.set(key, value)
在WeakMap中設置一組key關聯對象,返回這個 WeakMap
對象。
使用 WeakMap
const wm1 = new WeakMap(),
wm2 = new WeakMap(),
wm3 = new WeakMap();
const o1 = {},
o2 = function(){},
o3 = window;
wm1.set(o1, 37);
wm1.set(o2, "azerty");
wm2.set(o1, o2); // value能夠是任意值,包括一個對象或一個函數
wm2.set(o3, undefined);
wm2.set(wm1, wm2); // 鍵和值能夠是任意對象,甚至另一個WeakMap對象
wm1.get(o2); // "azerty"
wm2.get(o2); // undefined,wm2中沒有o2這個鍵
wm2.get(o3); // undefined,值就是undefined
wm1.has(o2); // true
wm2.has(o2); // false
wm2.has(o3); // true (即便值是undefined)
wm3.set(o1, 37);
wm3.get(o1); // 37
wm1.has(o1); // true
wm1.delete(o1);
wm1.has(o1); // false
實現一 個帶有 .clear() 方法的類 WeakMap
類
class ClearableWeakMap {
constructor(init) {
this._wm = new WeakMap(init)
}
clear() {
this._wm = new WeakMap()
}
delete(key) {
return this._wm.delete(key)
}
get(key) {
return this._wm.get(key)
}
has(key) {
return this._wm.has(key)
}
set(key, value) {
this._wm.set(key, value)
return this
}
}
本文分享自微信公衆號 - 人生代碼(lijinwen1996329ken)。
若有侵權,請聯繫 support@oschina.cn 刪除。
本文參與「OSC源創計劃」,歡迎正在閱讀的你也加入,一塊兒分享。