javascript JSON.stringifyでMapを扱う

javascript JSON.stringifyでMapを扱う

javascriptで、JSON.stringifyでMapを扱うサンプルコードを記述してます。「JSON.stringify」で「Map」は仕様で空のオブジェクトが返ります。なので、コールバック関数を使用してMapを変換して使用します。

環境

  • OS windows11 pro 64bit
  • Apache 2.4.43
  • ブラウザ chrome 108.0.5359.99

JSON.stringifyでMapを使う

通常「JSON.stringify」で「Map」を使用すると、仕様として空のオブジェクトが返ります。

const obj = { a: new Map([[1, "a"], [2, "b"]]) };

let result = JSON.stringify(obj);

console.log(result); // {"a":{}}

これを扱える形式に変換するには、
1. 「JSON.stringify」にコールバック関数を使用
2. コールバック関数内で「Map」だった場合はオブジェクトに変換する
ことで可能です。

const obj = { a: new Map([[1, "a"], [2, "b"]]),b: 111,c: 'aaa' };

let result = JSON.stringify(obj, (k, v) => {
    return (v instanceof Map) ? Object.fromEntries(v) : v
  }
);

console.log(result);
// {"a":{"1":"a","2":"b"},"b":111,"c":"aaa"}

以下のように、キーを指定してオブジェクトを生成することも可能です。

const obj = { a: new Map([[1, "a"], [2, "b"]]),b: 111,c: 'aaa' };

let result = JSON.stringify(obj, (k, v) => {
  return (v instanceof Map) ? {
      type: "Map",
      value: [...v]
    } : v
}
);

console.log(result);
// {"a":{"type":"Map","value":[[1,"a"],[2,"b"]]},"b":111,"c":"aaa"}

ちなみに「JSON.stringify」は、JSON 文字列に変換時に「undefined」や「関数」、「Symbol」などは有効な値とみなされずに除去されます。

const obj = {
  a: undefined,
  b: 'hoge',
  c: undefined,
  d: ()=>{},
  e: Symbol('hoge'),
};

console.log(JSON.stringify(obj)); 
// {"b":"hoge"}

サンプルコード

以下は、
「実行」ボタンをクリックすると、用意したMapが含まれるオブジェクトを「JSON.stringify」でJSON形式の文字列に変換して表示する
サンプルコードとなります。

※cssには「bootstrap material」を使用してます。関数はアロー関数で記述してます。

<!DOCTYPE html>
<html lang="ja">

<head>
  <meta charset="utf-8">
  <title>mebeeサンプル</title>
  <!-- MDB -->
  <link href="https://cdnjs.cloudflare.com/ajax/libs/mdb-ui-kit/4.2.0/mdb.min.css" rel="stylesheet" />
</head>

<body>

  <div class="container text-center w-75 mx-auto" style="margin-top:200px">

    <h2><span class="badge badge-info">結果</span></h2>

    <button type="button" onclick="changeObj()" class="btn btn-raised btn-info">
      実行
    </button>

  </div>

  <script>

    // Mapが含まれたオブジェクトを用意
    let obj = { a: new Map([[1, "a"], [2, "b"]]), b: 111, c: 'aaa' };

    const changeObj = () => {

      // 表示用要素取得
      let elm = document.getElementsByClassName("badge")[0];

      // JSON 文字列に変換して結果を表示
      elm.textContent = JSON.stringify(obj, (k, v) => { return (v instanceof Map) ? Object.fromEntries(v) : v });

    }

  </script>
</body>

</html>

変換されて表示されていることが確認できます。