6時だョ!!全員集合!!

Rails・JavaScrictを中心にアウトプットします。

2022年3月7日 [ES2015] Map/Set - マップとしてのObjectとMap (JavaScript Primer) マップとしてのObjectの利点

マップとしてのObjectの利点

Objectをマップとして使うときに起きる多くの問題は、Mapオブジェクトを使うことで解決しますが、 常にMapがObjectの代わりになるわけではありません。 マップとしてのObjectには次のような利点があります。

  • 多くの場合はMapオブジェクトを使うことで解決します。
  • MapがObjectの代わりにならないことがあります。

マップとしてのObjectには次のような利点があります

  • リテラル表現があるため作成しやすい
  • 規定のJSON表現があるため、JSON.stringify関数を使ってJSONに変換するのが簡単である
  • ネイティブAPI・外部ライブラリを問わず、多くの関数がマップとしてObjectを渡される設計になっている

次の例では、ログインフォームのsubmitイベントを受け取ったあと、サーバーにPOSTリクエストを送信しています。 サーバーにJSON文字列を送るために、JSON.stringify関数を使います。 そのため、Objectのマップを作ってフォームの入力内容を持たせています。 このような簡易なマップにおいては、Objectを使うほうが適切でしょう。

MapではなくObjectを使用した方が良い例

// URLとObjectのマップを受け取ってPOSTリクエストを送る関数
function sendPOSTRequest(url, data) {
    // XMLHttpRequestを使ってPOSTリクエストを送る
    const httpRequest = new XMLHttpRequest();
    httpRequest.setRequestHeader("Content-Type", "application/json");
    httpRequest.send(JSON.stringify(data));
    httpRequest.open("POST", url);
}

// formのsubmitイベントを受け取る関数
function onLoginFormSubmit(event) {
    const form = event.target;
    const data = {
        userName: form.elements.userName,
        password: form.elements.password,
    };
    sendPOSTRequest("/api/login", data);
}

サーバーにJSON文字列を送る際に、オブジェクトでマッピングしたdataを引数にJSON.stringify()を実行します。

XMLHttpRequestJavaScriptを使って、ブラウザとサーバー間で非同期通信でデータの送受信を可能にするオブジェクトです。

このオブジェクトは様々なメソッドを保有しており、それらのメソッドを使うことで、サーバーとのやり取りを行うことができます。

XMLHttpRequest.setRequestHeader()

HTTP リクエストヘッダーの値を設定します。

  • 第一引数に値を設定するヘッダーの名前
  • 第二引数にヘッダー本体として設定する値

XMLHttpRequest.send()

send() メソッドは、リクエストをサーバーに送信します。

  • 引数にリクエストの本文を指定(ここでいうとJSON)

XMLHttpRequest.open()

新しく作成されたリクエストを初期化したり、既存のリクエストを再初期化したりします。

  • 第一引数にHTTPリクエストメソッド
  • 第二引数にリクエストを送信するURL

ポイント

  • マッピングとは 2つの要素を関連付けること
  • MapにはMapリテラルがない
  • 今回のコードをMapで表現する場合、少なくともMapオブジェクトをNewする必要があり、複雑なコードになってしまう。

今回のJS primerのコード例ではMapを使わずにオブジェクトでMapを表現した方が良い例でしたが、Mapで書くとどうなってしまうのかと思考し、書いてみました。

マップとしてのObjectの書き方

const data = {
        userName: form.elements.userName,
        password: form.elements.password,
    };
console.log(JSON.stringify(data));

Map

const mapData = new Map ([["userNameKey", { userName: form.elements.userName }], ["passwordKey", { password: form.elements.password }]]);

const data = mapData.get("userNameKey");
console.log(JSON.stringify(data));
  • Mapにはリテラルがないのでnew演算子インスタンス化しています。
  • エントリーの値をオブジェクトにし、getメソッドで取り出しています。
  • 取り出した値にJSON.stringfyメソッドを使ってJSON形式にしています。
  • 今回の例だと、Mapを使わずにマップとしてのObjectを使用した方がわかりすいです。

末尾のカンマ

オブジェクトを代入する際にプロパティに末尾のカンマの必要性などが気になったため調べたところ、MDNに以下の記述がありました。

末尾のカンマ (「最後のカンマ」と呼ばれることもあります) は、JavaScript のコードに新しい要素や引数、プロパティを追加するときに役立ちます。新しいプロパティを追加するとき、最終行ですでに末尾のカンマを使用していれば、最終行を修正することなく新しい行を追加できます。これによって、バージョン管理の差分がより洗練され、コード編集の煩雑さを軽減できます。

参考

マップとしてのObjectとMap