プレーンな JS オブジェクトの代わりに Map を使用する場合

プレーンな JS オブジェクトの代わりに Map を使用する場合

1. マップは任意のタイプのキーを受け入れます

前述したように、オブジェクトのキーが文字列またはシンボルでない場合、JS は暗黙的にそれを文字列に変換します。

幸いなことに、マップキータイプは問題ありません

const numbersMap = 新しい Map();

numbersMap.set(1, 'one');
numbersMap.set(2, '2');

[...numbersMap.keys()]; // => [1, 2]

1 と 2 は numbersMap 内のキーであり、これらのキーの型 (数値) は同じままです。

MPA では、数値、ブール値、文字列、記号など、任意のキー タイプを使用できます。

booleanMap を新しい Map() に変換します。

booleansMap.set(true, "はい");
booleansMap.set(false, "いいえ");

[...booleansMap.keys()]; // => [true, false]

booleansMap はブール値をキーとして使用しますが、問題ありません。対照的に、ブールキーはプレーンオブジェクトでは機能しません。

想像を膨らませてみましょう。オブジェクト全体をマップのキーとして使用できますか? 答えは、はいです。

オブジェクトをキーとして

オブジェクトに関連付けられたデータを、そのオブジェクト自体に添付せずに保存する必要があるとします。これは、単純なオブジェクトでは不可能です。

回避策としては、オブジェクト値タプルの配列を使用することです。

const foo = { 名前: 'foo' };
const bar = { 名前: 'bar' };

定数kindOfMap = [
  [foo, 'Foo関連データ'],
  [バー、'バー関連データ']
]

kindOfMap は、オブジェクトと関連付けられた値のペアを含む配列です。

このアプローチの最大の問題は、キーによる値へのアクセスの複雑さが O(n) であり、キーによって目的の値を取得するには配列全体を走査する必要があることです。

関数 getByKey(kindOfMap, キー) {
  (const [k, v] の kindOfMap) {
    (キー === k) の場合 {
      v を返します。
    }
  }
  未定義を返します。
}

getByKey(kindOfMap, foo); // => 'Foo 関連データ'

WeakMap (Map の特殊バージョン) は、このような面倒なことをせずに上記のことを実行します。つまり、オブジェクトをキーとしてのみ受け入れます。

Map と Weakmap の主な違いは、Weakmap ではキー オブジェクトをガベージ コレクションできるため、メモリ リークを防ぐことができることです。

さて、WeakMap を使用して上記のコードをリファクタリングするのは非常に簡単です。

const foo = { 名前: 'foo' };
const bar = { 名前: 'bar' };

const mapOfObjects = 新しい WeakMap();

mapOfObjects.set(foo, 'Foo関連データ');
mapOfObjects.set(bar, 'バー関連データ');

mapOfObjects.get(foo); // => 'Foo 関連データ'

Map とは対照的に、WeakMap はキーとしてオブジェクトのみを受け入れ、メソッドの数も少なくなります。

2. マップにはキー名に関する制限はありません

JS 内のあらゆるオブジェクトはプロトタイプ オブジェクトからプロパティを継承し、通常のオブジェクトも同様です。

プロトタイプから継承したプロパティをオーバーライドすると、そのプロトタイプ プロパティに依存するコードが壊れる可能性があります。

関数isPlainObject(値) {
  戻り値.toString() === '[object オブジェクト]';
}

定数アクター = {
  名前: 'ハリソン・フォード'、
  toString: '俳優: ハリソン・フォード'
};

// 動作しません!
isPlainObject(actor); // TypeError: value.toString は関数ではありません

オブジェクト パーティシパントに定義されたプロパティ toString は、プロトタイプから継承された toString() メソッドをオーバーライドします。これは、toString() メソッドに依存しているため、isObject() を壊します。

通常のオブジェクトがプロトタイプから継承するプロパティとメソッドのリストを確認し、それらのメソッド名を使用してカスタム プロパティを定義しないようにしてください。

たとえば、いくつかのカスタム フィールドを管理するための UI があるとします。 ユーザーは名前と値を指定してカスタム フィールドを追加できます。

カスタム フィールドの状態をプレーン オブジェクトに保存すると便利です。

const ユーザーカスタムフィールド = {
  '色': '青'、
  'サイズ': '中',
  'toString': '青いボックス'
};

しかし、ユーザーが toString (例のように) などのカスタム フィールド名やコンストラクターなどを選択すると、オブジェクトが壊れる可能性があります。

ユーザー入力値をプレーンオブジェクトのキーとして使用しないでください。

マップにはこの問題はなく、キー値の名前は制限されません。

関数isMap(値) {
  戻り値.toString() === '[オブジェクト Map]';
}

アクターマップを新規マップ()に追加します。

actorMap.set('name', 'ハリソン・フォード');
actorMap.set('toString', '俳優: ハリソン・フォード');

// 動作します!
isMap(アクターマップ); // => true

actorMap に toString というプロパティがあるにもかかわらず、toString() メソッドは正常に動作します。

3. マップは反復可能

通常のオブジェクトのプロパティを反復処理するには、Object.keys() や Object.entries() などの他のヘルパー静的関数を使用する必要があります。

定数colorsHex = {
  '白': '#FFFFFF',
  '黒': '#000000'
};

Object.entries(colorsHex) の (const [color, hex]) {
  console.log(色、16進数);
}
// '白' '#FFFFFF'
// '黒' '#000000'

Object.entries(colorsHex) は、オブジェクトから抽出されたキーと値のペアの配列を返します。

ただし、 map 自体は反復可能です。

const colorsHexMap = 新しい Map();

colorsHexMap.set('white', '#FFFFFF');
colorsHexMap.set('黒', '#000000');

for (const [color, hex] of colorsHexMap) {
  console.log(色、16進数);
}
// '白' '#FFFFFF'
// '黒' '#000000'

colorsHexMap は反復可能です。反復可能オブジェクトが受け入れられる場所であればどこでも使用できます: for() ループ、スプレッド演算子 [...map] 。

Map は反復可能オブジェクトを返すメソッドを提供します: map.keys() はキーをトラバースし、map.values() は値をトラバースします

4. マップのサイズ

プレーン オブジェクトのもう 1 つの問題は、オブジェクトに含まれるプロパティの数がすぐにわからないことです。

const 試験 = {
  「ジョン・スミス」: 「10ポイント」
  「ジェーン・ドゥ」: 「8ポイント」
};

Object.keys(試験).length; // => 2

試験の規模を決定するには、すべてのキーを調べてその数を決定する必要があります。

マップには、属性の数を示すサイズ属性が用意されています。

const examsMap = 新しいMap([
  [「ジョン・スミス」、「10ポイント」]、
  [「ジェーン・ドゥ」、「8点」]、
]);
  
examsMap.size; // => 2

マップ内の属性の数を決定するのはさらに簡単です: examsMap.size。

上記は、通常の JS オブジェクトの代わりに Map を使用する場合の詳細です。JS オブジェクトの詳細については、123WORDPRESS.COM の他の関連記事に注目してください。

以下もご興味があるかもしれません:
  • データページング効果を実現する js オブジェクト
  • JSオブジェクトの走査順序の詳細な説明
  • JS オブジェクト配列の重複排除のための 3 つの方法の例と比較
  • JS オブジェクトのコピー (ディープ コピーとシャロー コピー)
  • js オブジェクト属性名でキャメルケースを下線に変換するサンプルコード
  • jsオブジェクトの読み取り速度の詳細な例

<<:  mysql5.7.21.zip インストールチュートリアル

>>:  MySQL 5.7.21 winx64 のインストールと設定方法のグラフィックチュートリアル

推薦する

NexusはAPIを使用して操作します

Nexus は RestApi を提供していますが、一部の API はまだ Groovy と組み合わ...

ページ内にマーキーとフラッシュが共存する場合の競合解決

競合の主な症状は、FLASH ボタンがジャンプし続け、不安定になり、Web ページの外観と通常のアク...

Docker共通コマンドの詳しい解説 Study03

目次1. ヘルプコマンド2. ミラーコマンド3. コンテナコマンド1. ヘルプコマンド1. 現在のD...

docker compose サービスの起動順序を制御する方法

まとめDocker-compose は複数の Docker コンテナ サービスを簡単に組み合わせるこ...

支払いカウントダウンを実現し、ホームページに戻るためのjs

ホーム ページに戻るための支払いカウントダウン ケースの概要: シンプルな js 構文、getEle...

SQL でテーブルにフィールドとコメントを追加する方法

1. フィールドを追加します。 alter table テーブル名 ADD フィールド名 タイプ;例...

SQLでEXPLAINコマンドを使用する方法

日常業務では、実行に時間のかかる SQL ステートメントを記録するために、スロー クエリを実行するこ...

Python Flask WeChat アプレットのログインプロセスとログイン API 実装コード

1. まずは効果を見てみましょうインターフェース要求によって返されるデータ: 2. 公式ログインフロ...

Linux の一般的なハードディスク管理コマンドの紹介

目次1. dfコマンド2. duコマンド3. fsckファイルシステム修復コマンド4. ディスクステ...

Robots.txtの詳細な紹介

Robots.txt はプレーンテキスト ファイルであり、Web サイト管理者は、ロボットによるアク...

vue cli で env を使用するガイド

目次序文紹介-公式設定例序文vueCli を使用してプロジェクトを開発したことのある方は、少しがっか...

MySQL 5.6 の「暗黙的な変換」によりインデックスが失敗し、データが不正確になる

背景SQL クエリを実行するときに、where 条件の vachar 型フィールドの単一引用符を削除...

MySQLクラスタのDockerデプロイメントの実装

シングルノードデータベースの欠点大規模なインターネットプログラムはユーザーベースが大きいため、アーキ...

MySQL フルテキスト インデックス、ジョイント インデックス、Like クエリ、JSON クエリのうち、どれが高速ですか?

目次クエリの背景1. クエリをいいね2. JSON関数クエリ3. 共同インデックスクエリ4. 全文イ...

Centos7 への mysql8.0rpm のインストール チュートリアル

まず、図をダウンロードしてください 1. まず、centos7に付属しているmariadbをアンイン...