1. 程式人生 > 程式設計 >JavaScript WeakMap使用詳解

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的資料請關注我們其它相關文章!