Weak Collectionsがデフォルトで有効になった
概要
ES2015で導入される機能である、Promise、WeakMap、WeakSetコンストラクタがデフォルトで有効になった。
Weak Collectionsについて
なぜ必要なのか
ES2015ではキーにオブジェクトも含む様々な型の値をとれる連想配列が導入された。
それらはCollectionsと呼ばれ、Map、Setコンストラクタとして提供される。
ここで、Mapの一部機能を自作してみると、
function MyMap() { this._keyTable = [] this._valTable = [] } MyMap.prototype.set = function (key, val) { this._keyTable.push(key) this._valTable.push(val) } MyMap.prototype.get = function (key) { var index = this._keyTable.indexOf(key) return this._valTable[index] }
このようになり、使うときは、
keyObj = {} mm = new MyMap mm.set(keyObj, 123) mm.get(keyObj) // 123
このようになる。
しかしこのようなMap実装には1つ欠点がある。
それは、他のkeyObjへの参照が全て無くなっても、mmインスタンスがkeyObjとそれに紐付けられた値をいつまでも保持するので、メモリリークの原因になってしまうということである。
単純な話、以下のようなコードですぐにメモリが枯渇してしまう。
while (true) mm.set({}, 123)
そこで登場するのがWeak CollectionsであるWeakMap、WeakSetであり、これらはkeyに取ったオブジェクトを弱参照で保持する。
つまり、他でそのオブジェクトが参照されなくなった時きちんとGCされ、valueを開放することができる。
API概略
作る
wm = new WeakMap ws = new WeakSet
加える
wm.set(keyObj, val) ws.add(keyObj)
調べる
wm.has(keyObj) // true ws.has(keyObj) // true
取り出す
wm.get(keyObj) // val
消す
wm.delete(keyObj) // true ws.delete(keyObj) // true
初期化する
WeakでないCollectionsと違ってclearメソッドによる初期化はできない。
デフォルトで有効になるバージョン
V8 (3.25.x) 3.26.31.8 3.31.14(-clear)
Chrome M36
Node 0.11.13