WeakMap
オブジェクトは、キーが弱く参照されるキーと値の組のコレクションです。キーはオブジェクトでなければならず、値は任意の値を取ることができます。
WeakMap
については、 WeakMap object in キー付きコレクション の節でより詳しく解説しています。
構文
new WeakMap([iterable])
引数
iterable
- 要素がキー・値の組 (2 要素の配列) である配列または他の反復処理可能なオブジェクトです。それぞれのキー・値の組が新しい WeakMap に追加されます。 null は undefined として扱われます。
解説
WeakMap のキーは Object
に限ります。プリミティブ型 はキーとして使えません(例えば Symbol
は WeakMap
のキーとして使えません)。
なぜ WeakMap なのか?
map API は、4 つの API メソッドから共有される 2 つの配列 (1 つはキー用、もう 1 つは値用) を用いることで、JavaScript で実装できます。このマップに要素を設定すると、それぞれの配列の最後に同時にキーと値を追加することになります。その結果、両方の配列でキーと値のインデックスは対応がとれています。マップから値を取得するには、すべてのキーを操作して一致するものを見つけ、見つかったキーのインデックスを使用して値の配列から対応する値を取り出します。
そうした実装では、主に 2 つの不都合が生じることとなります。1 つ目の不都合は、探索の計算量が O(n) となること (O(n) search) (n はマップ中におけるキーの数を表す)。もう 1 つの不都合はメモリーリークの問題です。 (2 つの配列を使って) マップを自作した場合、キーの配列はキーとしたオブジェクトへの参照を保持し続けるでしょう。従って、それらのキーとなったオブジェクトはガベージコレクションの対象から外されることとなります。
ネイティブな WeakMap では、キーとなるオブジェクトに対しては"弱い"参照が保持されます。これにより、キーとなったオブジェクトへの参照が他に存在しない場合に、そのオブジェクトはガベージコレクションの対象に含まれるようになります。ネイティブな WeakMap はキーとそのキーに関する情報をマッピングする場合に、キーがガベージコレクションされていないときにだけ意味があるため特に有用な構造です。
弱参照を用いるため、WeakMap
のキーは列挙できません (つまり、キーの一覧を取得するメソッドは存在しません)。もし、可能であれば、キーの一覧はガベージコレクションに依存することになり、非決定性が生まれます。キーの一覧が必要な場合は、Map
を使うことになります。
プロパティ
WeakMap.length
length
プロパティの値は0です。WeakMap.prototype
WeakMap
コンストラクターのプロトタイプを表します。どのWeakMap
オブジェクトも、プロパティを追加することが許可されています。
WeakMap
インスタンス
すべての WeakMap
インスタンスは、WeakMap.prototype
から継承します。
プロパティ
WeakMap.prototype.constructor
- インスタンスのプロトタイプを生成する関数を返します。これは、デフォルトでは
WeakMap
関数です。
メソッド
WeakMap.prototype.delete(key)
key
に関連した値を削除します。その後WeakMap.prototype.has(key)
はfalse
を返します。WeakMap.prototype.get(key)
key
に関連した値を返します。見つからない場合、undefined
を返します。WeakMap.prototype.has(key)
WeakMap
オブジェクト内にkey
に関連した値があるかどうか示す Boolean を返します。WeakMap.prototype.set(key, value)
WeakMap
オブジェクト内にkey
に対する値を設定し、WeakMap
オブジェクトを返します。WeakMap.prototype.clear()
WeakMap
オブジェクトからすべてのキー/バリューペアを削除します。.clear()
メソッドを持っていないWeakMap
オブジェクトをカプセル化することによって、.clear()
メソッドを持つ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); // 値は(オブジェクトまたは関数を含む)何であってもかまいません wm2.set(o3, undefined); wm2.set(wm1, wm2); // キーも値もどんなオブジェクトでもかまいません。 WeakMap であってもよいのです! wm1.get(o2); // "azerty" wm2.get(o2); // wm2 には o2 に関連付けられた値が無い為、undefined が返ってきます wm2.get(o3); // 値が undefined と関連付けられている為、undefined が返ってきます wm1.has(o2); // true wm2.has(o2); // false wm2.has(o3); // true (値が関連付けられているならば、たとえ値が 'undefined' であっても true となります) 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 } }
仕様書
仕様書 | 状態 | 備考 |
---|---|---|
ECMAScript Latest Draft (ECMA-262) WeakMap の定義 |
ドラフト | |
ECMAScript 2015 (6th Edition, ECMA-262) WeakMap の定義 |
標準 | 初回定義 |
ブラウザーの互換性
デスクトップ | モバイル | サーバー | |||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|
WeakMap | Chrome 完全対応 36 | Edge 完全対応 12 | Firefox 完全対応 6 | IE 完全対応 11 | Opera 完全対応 23 | Safari 完全対応 8 | WebView Android 完全対応 37 | Chrome Android 完全対応 36 | Firefox Android 完全対応 6 | Opera Android 完全対応 24 | Safari iOS 完全対応 8 | Samsung Internet Android 完全対応 3.0 | nodejs
完全対応
0.12
|
clear | Chrome 未対応 36 — 43 | Edge 未対応 なし | Firefox 未対応 20 — 46 | IE 完全対応 11 | Opera 未対応 25 — 30 | Safari 未対応 8 — 9 | WebView Android 未対応 37 — 43 | Chrome Android 未対応 36 — 43 | Firefox Android 未対応 20 — 46 | Opera Android 未対応 25 — 30 | Safari iOS 未対応 8 — 9 | Samsung Internet Android 未対応 3.0 — 4.0 | nodejs 完全対応 あり |
delete | Chrome 完全対応 36 | Edge 完全対応 12 | Firefox
完全対応
6
| IE 完全対応 11 | Opera 完全対応 23 | Safari 完全対応 8 | WebView Android 完全対応 37 | Chrome Android 完全対応 36 | Firefox Android
完全対応
6
| Opera Android 完全対応 24 | Safari iOS 完全対応 8 | Samsung Internet Android 完全対応 3.0 | nodejs
完全対応
0.12
|
get | Chrome 完全対応 36 | Edge 完全対応 12 | Firefox
完全対応
6
| IE 完全対応 11 | Opera 完全対応 23 | Safari 完全対応 8 | WebView Android 完全対応 37 | Chrome Android 完全対応 36 | Firefox Android
完全対応
6
| Opera Android 完全対応 24 | Safari iOS 完全対応 8 | Samsung Internet Android 完全対応 3.0 | nodejs
完全対応
0.12
|
has | Chrome 完全対応 36 | Edge 完全対応 12 | Firefox
完全対応
6
| IE 完全対応 11 | Opera 完全対応 23 | Safari 完全対応 8 | WebView Android 完全対応 37 | Chrome Android 完全対応 36 | Firefox Android
完全対応
6
| Opera Android 完全対応 24 | Safari iOS 完全対応 8 | Samsung Internet Android 完全対応 3.0 | nodejs
完全対応
0.12
|
prototype | Chrome 完全対応 36 | Edge 完全対応 12 | Firefox 完全対応 6 | IE 完全対応 11 | Opera 完全対応 23 | Safari 完全対応 8 | WebView Android 完全対応 37 | Chrome Android 完全対応 36 | Firefox Android 完全対応 6 | Opera Android 完全対応 24 | Safari iOS 完全対応 8 | Samsung Internet Android 完全対応 3.0 | nodejs
完全対応
0.12
|
set | Chrome 完全対応 36 | Edge 完全対応 12 | Firefox
完全対応
6
| IE
部分対応
11
| Opera 完全対応 23 | Safari 完全対応 8 | WebView Android 完全対応 37 | Chrome Android 完全対応 36 | Firefox Android
完全対応
6
| Opera Android 完全対応 24 | Safari iOS 完全対応 8 | Samsung Internet Android 完全対応 3.0 | nodejs
完全対応
0.12
|
new WeakMap(iterable) | Chrome 完全対応 38 | Edge 完全対応 12 | Firefox 完全対応 36 | IE 未対応 なし | Opera 完全対応 25 | Safari 完全対応 9 | WebView Android 完全対応 38 | Chrome Android 完全対応 38 | Firefox Android 完全対応 36 | Opera Android 完全対応 25 | Safari iOS 完全対応 9 | Samsung Internet Android 完全対応 3.0 | nodejs 完全対応 0.12 |
new WeakMap(null) | Chrome 完全対応 36 | Edge 完全対応 12 | Firefox 完全対応 37 | IE 完全対応 11 | Opera 完全対応 23 | Safari 完全対応 8 | WebView Android 完全対応 37 | Chrome Android 完全対応 36 | Firefox Android 完全対応 37 | Opera Android 完全対応 24 | Safari iOS 完全対応 8 | Samsung Internet Android 完全対応 3.0 | nodejs
完全対応
0.12
|
WeakMap() without new throws | Chrome 完全対応 36 | Edge 完全対応 12 | Firefox 完全対応 42 | IE 完全対応 11 | Opera 完全対応 23 | Safari 完全対応 9 | WebView Android 完全対応 37 | Chrome Android 完全対応 36 | Firefox Android 完全対応 42 | Opera Android 完全対応 24 | Safari iOS 完全対応 9 | Samsung Internet Android 完全対応 3.0 | nodejs 完全対応 0.12 |
凡例
- 完全対応
- 完全対応
- 部分対応
- 部分対応
- 未対応
- 未対応
- 非標準。ブラウザー間の互換性が低い可能性があります。
- 非標準。ブラウザー間の互換性が低い可能性があります。
- 非推奨。新しいウェブサイトでは使用しないでください。
- 非推奨。新しいウェブサイトでは使用しないでください。
- 実装ノートを参照してください。
- 実装ノートを参照してください。
- ユーザーが明示的にこの機能を有効にしなければなりません。
- ユーザーが明示的にこの機能を有効にしなければなりません。