`WeakMap` 对象是一组键/值对的集合，其中的键是弱引用的。其键必须是对象，而值可以是任意的。

你可以从这里了解更多关于`WeakMap`的内容:WeakMap object in 带键的集合.

## 语法

    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.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.prototype.clear()`
  从`WeakMap中移除所有的` key/value 。 注意，该方法已弃用,但可以通过创建一个空的WeakMap并替换原对象来实现 (参看 `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 Latest Draft (ECMA-262) WeakMap | Draft |

## 浏览器兼容性

The compatibility table on this page is generated from structured data. If you'd like to contribute to the data, please check out https://github.com/mdn/browser-compat-data and send us a pull request.

Update compatibility data on GitHub

| Desktop | Mobile | Server
| Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | Android webview | Chrome for Android | Edge Mobile | Firefox for Android | Opera for Android | Safari on iOS | Samsung Internet | Node.js
`WeakMap` | Chrome Full support 36 | Edge Full support 12 | Firefox Full support 6 | IE Full support 11 | Opera Full support 23 | Safari Full support 8 | WebView Android Full support 37 | Chrome Android Full support 36 | Edge Mobile Full support 12 | Firefox Android Full support 6 | Opera Android Full support 23 | Safari iOS Full support 8 | Samsung Internet Android Full support Yes | nodejs Full support 0.12 Full support 0.12 Full support 0.10 Disabled Disabled From version 0.10: this feature is behind the `--harmony` runtime flag.
`new WeakMap(iterable)` | Chrome Full support 38 | Edge Full support 12 | Firefox Full support 36 | IE No support No | Opera Full support 25 | Safari Full support 9 | WebView Android Full support 38 | Chrome Android Full support 38 | Edge Mobile Full support 12 | Firefox Android Full support 36 | Opera Android Full support 25 | Safari iOS Full support 9 | Samsung Internet Android Full support Yes | nodejs Full support 0.12
`new WeakMap(null)` | Chrome Full support Yes | Edge Full support 12 | Firefox Full support 37 | IE Full support 11 | Opera ? | Safari Full support 8 | WebView Android Full support Yes | Chrome Android Full support Yes | Edge Mobile Full support 12 | Firefox Android Full support 37 | Opera Android ? | Safari iOS Full support 8 | Samsung Internet Android Full support Yes | nodejs Full support 0.12 Full support 0.12 Full support 0.10 Disabled Disabled From version 0.10: this feature is behind the `--harmony` runtime flag.
`WeakMap()` without `new` throws | Chrome Full support Yes | Edge Full support 12 | Firefox Full support 42 | IE Full support 11 | Opera Full support Yes | Safari Full support 9 | WebView Android Full support Yes | Chrome Android Full support Yes | Edge Mobile Full support 12 | Firefox Android Full support 42 | Opera Android Full support Yes | Safari iOS Full support 9 | Samsung Internet Android Full support Yes | nodejs Full support 0.12
`clear` Deprecated Non-standard | Chrome No support 36 — 43 | Edge No support No | Firefox No support 20 — 46 | IE Full support 11 | Opera No support 25 — 30 | Safari No support 8 — 9 | WebView Android No support 37 — 43 | Chrome Android No support 36 — 43 | Edge Mobile No support No | Firefox Android No support 20 — 46 | Opera Android No support 25 — 30 | Safari iOS No support 8 — 9 | Samsung Internet Android Full support Yes | nodejs Full support Yes
`delete` | Chrome Full support 36 | Edge Full support 12 | Firefox Full support 6 Notes Full support 6 Notes Notes Prior to Firefox 38, this method threw a `TypeError` when the key parameter was not an object. This has been fixed in version 38 and later to return `false` as per the ES2015 standard. | IE Full support 11 | Opera Full support 23 | Safari Full support 8 | WebView Android Full support 37 | Chrome Android Full support 36 | Edge Mobile Full support Yes | Firefox Android Full support 6 Notes Full support 6 Notes Notes Prior to Firefox 38, this method threw a `TypeError` when the key parameter was not an object. This has been fixed in version 38 and later to return `false` as per the ES2015 standard. | Opera Android Full support 23 | Safari iOS Full support 8 | Samsung Internet Android Full support Yes | nodejs Full support 0.12 Full support 0.12 Full support 0.10 Disabled Disabled From version 0.10: this feature is behind the `--harmony` runtime flag.
`get` | Chrome Full support 36 | Edge Full support 12 | Firefox Full support 6 Notes Full support 6 Notes Notes Prior to Firefox 38, this method threw a `TypeError` when the key parameter was not an object. However, the ES2015 specification specifies to return `undefined` instead. Furthermore, `WeakMap.prototype.get` accepted an optional second argument as a fallback value, which is not part of the standard. Both non-standard behaviors are removed in version 38 and higher. | IE Full support 11 | Opera Full support 23 | Safari Full support 8 | WebView Android Full support 37 | Chrome Android Full support 36 | Edge Mobile Full support Yes | Firefox Android Full support 6 Notes Full support 6 Notes Notes Prior to Firefox 38, this method threw a `TypeError` when the key parameter was not an object. However, the ES2015 specification specifies to return `undefined` instead. Furthermore, `WeakMap.prototype.get` accepted an optional second argument as a fallback value, which is not part of the standard. Both non-standard behaviors are removed in version 38 and higher. | Opera Android Full support 23 | Safari iOS Full support 8 | Samsung Internet Android Full support Yes | nodejs Full support 0.12 Full support 0.12 Full support 0.10 Disabled Disabled From version 0.10: this feature is behind the `--harmony` runtime flag.
`has` | Chrome Full support 36 | Edge Full support 12 | Firefox Full support 6 Notes Full support 6 Notes Notes Prior to Firefox 38, this method threw a `TypeError` when the key parameter was not an object. This has been fixed in version 38 and later to return `false` as per the ES2015 standard. | IE Full support 11 | Opera Full support 23 | Safari Full support 8 | WebView Android Full support 37 | Chrome Android Full support 36 | Edge Mobile Full support Yes | Firefox Android Full support 6 Notes Full support 6 Notes Notes Prior to Firefox 38, this method threw a `TypeError` when the key parameter was not an object. This has been fixed in version 38 and later to return `false` as per the ES2015 standard. | Opera Android Full support 23 | Safari iOS Full support 8 | Samsung Internet Android Full support Yes | nodejs Full support 0.12 Full support 0.12 Full support 0.10 Disabled Disabled From version 0.10: this feature is behind the `--harmony` runtime flag.
`prototype` | Chrome Full support 36 | Edge Full support Yes | Firefox Full support 6 | IE Full support 11 | Opera Full support 23 | Safari Full support 8 | WebView Android Full support 37 | Chrome Android Full support 36 | Edge Mobile Full support Yes | Firefox Android Full support 6 | Opera Android Full support 23 | Safari iOS Full support 8 | Samsung Internet Android Full support Yes | nodejs Full support 0.12 Full support 0.12 Full support 0.10 Disabled Disabled From version 0.10: this feature is behind the `--harmony` runtime flag.
`set` | Chrome Full support 36 | Edge Full support 12 | Firefox Full support 6 Notes Full support 6 Notes Notes Prior to Firefox 38, this method threw a `TypeError` when the key parameter was not an object. This has been fixed in version 38 and later to return `false` as per the ES2015 standard. | IE Partial support 11 Notes Partial support 11 Notes Notes Returns 'undefined' instead of the 'Map' object. | Opera Full support 23 | Safari Full support 8 | WebView Android Full support 37 | Chrome Android Full support 36 | Edge Mobile Full support Yes | Firefox Android Full support 6 Notes Full support 6 Notes Notes Prior to Firefox 38, this method threw a `TypeError` when the key parameter was not an object. This has been fixed in version 38 and later to return `false` as per the ES2015 standard. | Opera Android Full support 23 | Safari iOS Full support 8 | Samsung Internet Android Full support Yes | nodejs Full support 0.12 Full support 0.12 Full support 0.10 Disabled Disabled From version 0.10: this feature is behind the `--harmony` runtime flag.

### Legend

Full support
  Full support
Partial support
  Partial support
No support
  No support
Compatibility unknown
  Compatibility unknown
Non-standard. Expect poor cross-browser support.
  Non-standard. Expect poor cross-browser support.
Deprecated. Not for use in new websites.
  Deprecated. Not for use in new websites.
See implementation notes.
  See implementation notes.
User must explicitly enable this feature.
  User must explicitly enable this feature.

## 相关链接

- WeakMap bug at Mozilla
- Hiding Implementation Details with ECMAScript 6 WeakMaps
- `Map`
- `Set`
- `WeakSet`