Vue 3 高階指南之 WeakMap

高階指南之 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源創計劃」,歡迎正在閱讀的你也加入,一塊兒分享。

相關文章
相關標籤/搜索