JavaScript WeakMap使用詳解
WeakMap物件是一組鍵/值對的集合,其中的鍵是弱引用的。其鍵必須是物件,而值可以是任意的。
語法
new WeakMap([iterable])
引數
iterable
Iterable 是一個數組(二元陣列)或者其他可迭代的且其元素是鍵值對的物件。每個鍵值對會被加到新的WeakMap 裡。null 會被當做 undefined。
描述
WeakMap 的 key 只能是Object型別。原始資料型別 是不能作為 key 的(比如 Symbol)。
Why WeakMap?
在 JavaScript 裡,map API 可以通過使其四個 API 方法共用兩個陣列(一個存放鍵,一個存放值)來實現。給這種map 設定值時會同時將鍵和值新增到這兩個陣列的末尾。從而使得鍵和值的索引在兩個陣列中相對應。當從該 map 取值的時候,需要遍歷所有的鍵,然後使用索引從儲存值的陣列中檢索出相應的值。
但這樣的實現會有兩個很大的缺點,首先賦值和搜尋操作都是 O(n) 的時間複雜度( n 是鍵值對的個數),因為這兩個操作都需要遍歷全部整個陣列來進行匹配。另外一個缺點是可能會導致記憶體洩漏,因為陣列會一直引用著每個鍵和值。這種引用使得垃圾回收演算法不能回收處理他們,即使沒有其他任何引用存在了。
相比之下,原生的 WeakMap 持有的是每個鍵物件的“弱引用”,這意味著在沒有其他引用存在時垃圾回收能正確進行。原生 WeakMap 的結構是特殊且有效的,其用於對映的 key 只有在其沒有被回收時才是有效的。
正由於這樣的弱引用,WeakMap 的 key是不可列舉的 (沒有方法能給出所有的 key)。如果key 是可列舉的話,其列表將會受垃圾回收機制的影響,從而得到不確定的結果。因此,如果你想要這種型別物件的key 值的列表,你應該使用 Map。
基本上,如果你要往物件上新增資料,又不想幹擾垃圾回收機制,就可以使用 WeakMap。
屬性
- WeakMap.length
length 屬性的值為0。
- WeakMap.prototype
WeakMap 構造器的原型。允許新增屬性到所有的 WeakMap 物件。
WeakMap例項
所有WeakMap例項繼承自WeakMap.prototype.
屬性
WeakMap.prototype.constructor
返回建立WeakMap例項的原型函式。 WeakMap函式是預設的。
方法
- WeakMap.prototype.delete(key)
移除key的關聯物件。執行後 WeakMap.prototype.has(key)返回false。
- WeakMap.prototype.get(key)
返回key關聯物件,或者 undefined(沒有key關聯物件時)。
- 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(k) { return this._wm.delete(k) } get(k) { return this._wm.get(k) } has(k) { return this._wm.has(k) } set(k,v) { this._wm.set(k,v) return this } }
規範
Specification | Status | Comment |
---|---|---|
ECMAScript 2015 (6th Edition,ECMA-262) WeakMap |
Standard | Initial definition. |
ECMAScript (ECMA-262) WeakMap |
Living Standard |
以上就是JavaScript WeakMap使用詳解的詳細內容,更多關於JavaScript WeakMap的資料請關注我們其它相關文章!