📚

JavaScriptでMapのキーにオブジェクトを使う際の注意点と解決方法

に公開

JavaScriptのMapは、キーと値のペアを保持するための便利なデータ構造です。

しかし、キーとしてオブジェクトを使用する場合には注意が必要です。

以下のコードがundefinedを出力する理由とその対策について説明します。

const map = new Map();
map.set({a: 1}, "foo");
console.log(map.get({a: 1})); // "undefined"と表示される

問題の原因

上記のコードでは、mapにオブジェクト{a: 1}をキーとして値fooをセットしています。

同じ形状のオブジェクト{a: 1}を使って値を取得しようとすると、undefinedが表示されます。

これは、JavaScriptではオブジェクトが参照によって比較されるためです。map.setで使用したオブジェクトとmap.getで使用したオブジェクトは異なるメモリ参照を持つため、同じキーとは認識されません。

解決方法

この問題を解決するための方法をいくつか紹介します。

1. 同じオブジェクト参照を使用する

const map = new Map();
const key = {a: 1};
map.set(key, "foo");
console.log(map.get(key)); // "foo"と表示される

同じオブジェクト参照を使用することで、期待通りの結果が得られます。

2. プリミティブ値をキーとして使用する

const map = new Map();
const key = JSON.stringify({a: 1});
map.set(key, "foo");
console.log(map.get(JSON.stringify({a: 1}))); // "foo"と表示される

オブジェクトを文字列に変換してキーとして使用します。同じ構造のオブジェクトは同じ文字列になるため、意図した通りに動作します。

3. WeakMapの使用

const map = new WeakMap();
const key = {a: 1};
map.set(key, "foo");
console.log(map.get(key)); // "foo"と表示される

WeakMapを使用することで、オブジェクトがガベージコレクションの対象になります。キーとしてオブジェクトを使用し、同じ参照を保持する場合に有効です。

以上が解決方法となります。

最後に

実装でハマってしまい、学んだはいいものの、すぐに忘れてしまいそうなので記事に残しました。

Discussion