1. 「(普通の)参照」と「弱い参照」
例えば以下のように、{ name; 'foo' }
というオブジェクトが obj
という変数にセットされた場合、このオブジェクトは obj
という変数によって「参照」されていると言えます。
let obj = { name: 'foo' }
このように、あるオブジェクトへの「(普通の)参照」が存在している間、そのオブジェクトがメモリ上から勝手に削除されることはありません。まだそのオブジェクトは使われる可能性がありますので。当たり前の話ではあります。
しかし、この後 この obj
が別のオブジェクトを参照したとします。
obj = { name: 'bar' }
すると、最初のオブジェクト { name: 'foo' }
はどこからも参照されなくなったため(使いたくてもアクセスできません)、必要ないと判断され、どこかしらのタイミングでメモリ上から削除されてしまいます。(この機能を、ガベージコレクションと言います)
これに対して「弱い参照」は、参照ではあるけれども、ガベージコレクションによる削除対象となる参照です。つまり、そのオブジェクトはいずれメモリ上から削除されます。
2. JavaScript で「弱い参照」を扱う
JavaScript で「弱い参照」を作成するには、WeakRef というオブジェクトを使います。
2-1.「弱い参照」を作成する
あるオブジェクトが変数 obj
にセットされているとします(普通の「参照」です)。
let obj = { name: "foo" }
この obj
を引数にして、WeakRef オブジェクトを作成します。
const weakRef = new WeakRef(obj)
元のオブジェクトに対する「弱い参照」を保持したオブジェクトができました。
この後、obj
が別のオブジェクトを参照したとしましょう。
obj = { name: 'bar'}
すると、元のオブジェクト { name: 'foo'}
は、「弱い参照」はあるものの 普通の「参照」はなくなりますので、ガベージコレクションによる削除対象になります。
2-2. 参照先のオブジェクトを取得する
参照先のオブジェクトを取得するには、WeakRef オブジェクトの deref メソッドを使います。参照先が既に削除されている場合は undefined
を返しますので、参照先が削除されたかどうかの判定にも使用できます。
weakRef.deref()
3. おわりに
実際に使う機会は、あまりないのではないでしょうか。
4. 参考
- ECMAScript® 2023 Language Specification
- WeakRef – JavaScript | MDN
- JavaScript built-in: WeakRef | Can I use…
- WeakRef: JavaScriptに弱参照がやってくる(ついでにFinalizationも) – Qiita