WeakMap

WeakMap 对象是键/值对的集合,且其中的键是弱引用的。其键只能是对象,而值则可以是任意的。

语法

new WeakMap([iterable])

参数

iterable
Iterable 是一个数组(2元数组)或者可遍历的且其元素是键值对的对象。每个键值对会被加到新的 WeakMap 里。

描述

WeakMap 的 key 只能是对象类型。 原始数据类型 是不能作为 key 的(比如 Symbol)。

Why WeakMap?

经验丰富的 JavaScript 程序员会注意到,WeakMap 完全可以通过两个数组(一个存放键,一个存放值)来实现。但这样的实现会有两个很大的缺点,首先是O(n)的时间复杂度(n是键值对的个数)。另外一个则可能会导致内存泄漏:在这种自己实现的 WeakMap 中,存放键的数组中的每个索引将会保持对所引用对象的引用,阻止他们被当作垃圾回收.而在原生的WeakMap中,每个键对自己所引用对象的引用是 "弱引用", 这意味着,如果没有其他引用和该键引用同一个对象,这个对象将会被当作垃圾回收.

正由于这样的弱引用,WeakMap 的 key 是非枚举的 (没有方法能给出所有的 key)。如果key 是可枚举的话,其列表将会受垃圾回收机制的影响,从而得到不确定的结果. 因此,如果你想要这种类型对象的 key 值的列表,你应该使用 Map

属性

WeakMap.length
length 属性的值为 0。
WeakMap.prototype
WeakMap 构造器的原型。 允许添加属性到所有的 WeakMap 对象。

WeakMap 实例

所有 WeakMap 实例继承自 WeakMap.prototype.

属性

WeakMap.prototype.constructor
Returns the function that created an instance's prototype. This is the WeakMap function by default.

方法

WeakMap.prototype.delete(key)
Removes any value associated to the key. WeakMap.prototype.has(key) will return false afterwards.
WeakMap.prototype.get(key)
Returns the value associated to the key, or undefined if there is none.
WeakMap.prototype.has(key)
Returns a Boolean asserting whether a value has been associated to the key in the WeakMap object or not.
WeakMap.prototype.set(key, value)
Sets the value for the key in the WeakMap object. Returns the WeakMap object.
WeakMap.prototype.clear()
Removes all key/value pairs from the WeakMap object. Note that it is possible to implement a WeakMap-like object that has a .clear() method by encapsulating a WeakMap object that hasn't it (see example on page WeakMap)

例子

使用 WeakMap

var wm1 = new WeakMap(),
    wm2 = new WeakMap(),
    wm3 = new WeakMap();
var 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
wm3.clear();
wm3.get(o1); // undefined,wm3已被清空
wm1.has(o1);   // true
wm1.delete(o1);
wm1.has(o1);   // false

用 .clear() 方法实现伪 WeakMap 

为了更好的说明,下面使用了 ECMAScript6 新增的 class 构造函数,其目前没有广泛实现。

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 2017 Draft (ECMA-262)
WeakMap
Draft  

浏览器兼容性

Feature Chrome Firefox (Gecko) Internet Explorer Opera Safari
Basic support 36 6.0 (6.0) 11 23 7.1
new WeakMap(iterable) 38 36 (36) 未实现 25 未实现
clear() 36 未实现 [1] 11 23 7.1
Constructor argument: new WeakMap(null) (Yes) 37 (37) 11 ? ?
Monkey-patched set() in constructor (Yes) 37 (37) ? ? ?
WeakMap() without new throws (Yes) 42 (42) 11 ? ?
Feature Chrome for Android Firefox Mobile (Gecko) IE Mobile Opera Mobile Safari Mobile
Basic support 35 6.0 (6.0) 未实现 未实现 8
new WeakMap(iterable) 38 36.0 (36) 未实现 未实现 未实现
clear() 35 未实现 [1] 未实现 未实现 8
Constructor argument: new WeakMap(null) ? 37.0 (37) 未实现 ? ?
Monkey-patched set() in constructor ? 37.0 (37) 未实现 ? ?
WeakMap() without new throws ? 42.0 (42) ? ? ?

相关链接

文档标签和贡献者

 此页面的贡献者: Ende93, Cattla, teoli, ziyunfei
 最后编辑者: Ende93,