WeakSet

WeakSet オブジェクトは、コレクションに弱く参照されたオブジェクトを格納することができます。

解説

WeakSet オブジェクトはコレクションオブジェクトです。 Set と同様に、 WeakSet 内の各オブジェクトは一度だけ存在します。すなわち、 WeakSet コレクション内で固有になります。

Set オブジェクトとの主な違いは下記の通りです。

  • WeakSetオブジェクトのみのコレクションです。 Set のように、任意の型の自由な値を入れることはできません。
  • WeakSet弱い参照です。コレクション内のオブジェクトへの弱い参照で保持されます。 WeakSet 内に格納されているオブジェクトへの参照が他にない場合、ガベージコレクションにより削除されます。

    注: これは、このコレクションに格納されているオブジェクトの現在のリストが存在しないことを意味します。 WeakSets は列挙可能ではありません。

使用例: 循環参照の検出

自分自身を再帰的に呼び出す関数は、どのオブジェクトが処理済みであるかを追跡することで、循環したデータ構造を防ぐ必要があります。

WeakSet はこの目的に理想的です。

// Execute a callback on everything stored inside an object
function execRecursively(fn, subject, _refs = null){
  if(!_refs)
    _refs = new WeakSet();
  
  // Avoid infinite recursion
  if(_refs.has(subject))
    return;

  fn(subject);
  if("object" === typeof subject){
    _refs.add(subject);
    for(let key in subject)
      execRecursively(fn, subject[key], _refs);
  }
}

const foo = {
  foo: "Foo",
  bar: {
    bar: "Bar"
  }
};

foo.bar.baz = foo; // Circular reference!
execRecursively(obj => console.log(obj), foo);

ここで、 WeakSet は最初の実行時に作成され、その後の関数呼び出しのたびに (内部の _refs 引数を使用して) 渡されます。

オブジェクトの数や探索順序は重要ではないので、オブジェクトの参照を追跡するには WeakSet のほうが Set よりも、特に巨大な数のオブジェクトを処理する場合にはよりふさわしい (そして性能もよい) ものです。

コンストラクター

WeakSet()
新しいWeakSetオブジェクトを生成します。

インスタンスメソッド

WeakSet.prototype.add(value)
valueWeakSet オブジェクトに追加します。
WeakSet.prototype.delete(value)
valueWeakSet オブジェクトから削除します。削除後、 WeakSet.prototype.has(value)false を返します。
WeakSet.prototype.has(value)
valueWeakSet オブジェクト内の要素に含まれているかどうかを示す論理値を返します。

WeakSet オブジェクトの使用

const ws = new WeakSet();
const foo = {};
const bar = {};

ws.add(foo);
ws.add(bar);

ws.has(foo);    // true
ws.has(bar);    // true

ws.delete(foo); // foo を set から削除
ws.has(foo);    // false, foo は削除済み
ws.has(bar);    // true, bar は残っている

foo !== bar であることに注意してください。これらは似たオブジェクトですが、まったく同じオブジェクトではありません。したがって、両方のオブジェクトが set に追加されます。

仕様書

仕様書
ECMAScript (ECMA-262)
WeakSet の定義

ブラウザーの互換性

Update compatibility data on GitHub
デスクトップモバイルサーバー
ChromeEdgeFirefoxInternet ExplorerOperaSafariAndroid webviewAndroid 版 ChromeAndroid 版 FirefoxAndroid 版 OperaiOSのSafariSamsung InternetNode.js
WeakSetChrome 完全対応 36Edge 完全対応 12Firefox 完全対応 34IE 未対応 なしOpera 完全対応 23Safari 完全対応 9WebView Android 完全対応 37Chrome Android 完全対応 36Firefox Android 完全対応 34Opera Android 完全対応 24Safari iOS 完全対応 9Samsung Internet Android 完全対応 3.0nodejs 完全対応 0.12
WeakSet() constructorChrome 完全対応 36Edge 完全対応 12Firefox 完全対応 34IE 未対応 なしOpera 完全対応 23Safari 完全対応 9WebView Android 完全対応 37Chrome Android 完全対応 36Firefox Android 完全対応 34Opera Android 完全対応 24Safari iOS 完全対応 9Samsung Internet Android 完全対応 3.0nodejs 完全対応 0.12
addChrome 完全対応 36Edge 完全対応 12Firefox 完全対応 34IE 未対応 なしOpera 完全対応 23Safari 完全対応 9WebView Android 完全対応 37Chrome Android 完全対応 36Firefox Android 完全対応 34Opera Android 完全対応 24Safari iOS 完全対応 9Samsung Internet Android 完全対応 3.0nodejs 完全対応 0.12
clear
非推奨非標準
Chrome 未対応 36 — 41Edge 未対応 なしFirefox 未対応 34 — 46IE 未対応 なしOpera 未対応 23 — 28Safari 未対応 なしWebView Android 未対応 37 — 41Chrome Android 未対応 36 — 41Firefox Android 未対応 34 — 46Opera Android 未対応 24 — 28Safari iOS 未対応 なしSamsung Internet Android 未対応 3.0 — 4.0nodejs 未対応 なし
deleteChrome 完全対応 36Edge 完全対応 12Firefox 完全対応 34IE 未対応 なしOpera 完全対応 23Safari 完全対応 9WebView Android 完全対応 37Chrome Android 完全対応 36Firefox Android 完全対応 34Opera Android 完全対応 24Safari iOS 完全対応 9Samsung Internet Android 完全対応 3.0nodejs 完全対応 0.12
hasChrome 完全対応 36Edge 完全対応 12Firefox 完全対応 34IE 未対応 なしOpera 完全対応 23Safari 完全対応 9WebView Android 完全対応 37Chrome Android 完全対応 36Firefox Android 完全対応 34Opera Android 完全対応 24Safari iOS 完全対応 9Samsung Internet Android 完全対応 3.0nodejs 完全対応 0.12

凡例

完全対応  
完全対応
未対応  
未対応
非標準。ブラウザー間の互換性が低い可能性があります。
非標準。ブラウザー間の互換性が低い可能性があります。
非推奨。新しいウェブサイトでは使用しないでください。
非推奨。新しいウェブサイトでは使用しないでください。

関連情報