プレーンな 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 のインストールと設定方法のグラフィックチュートリアル

推薦する

Docker CPU 制限の実装

1. --cpu=<値> 1) コンテナが使用できるCPUリソースの量を指定しますが、コ...

Dell R720 サーバーに Windows Server 2008 R2 をインストールする方法

注: この記事のすべての写真はインターネットから収集されたものであるため、DELL R720 サーバ...

MySQLがサブクエリと結合の使用を推奨しない理由

ページ分割されたクエリを実行するには: 1. MySQL の場合、サブクエリと結合の使用は推奨されま...

Windows7 での Mysql5.7 my.ini ファイルの読み込みパスとデータの場所の変更方法

更新: MySQL の公式 Web サイトにアクセスして MySQL インストーラーをインストールし...

Linuxグループの基礎知識ポイントまとめ

1. Linuxグループの基本紹介Linux では、すべてのユーザーはグループに所属する必要があり、...

Ubuntu のインストール グラフィック ドライバーと Cuda チュートリアル

目次1. 元のドライバーをアンインストールする2. 新しいグラフィックカードドライバーをダウンロード...

MySQL データベースの基本的な SQL ステートメントの概要

この記事では、例を使用して、Mysql データベースの基本的な SQL ステートメントについて説明し...

MySQL初心者のための基本操作のまとめ

図書館運営クエリ1.SHOW DATABASE; ----すべてのデータベースを照会する2. SHO...

Dockerfile を使用して Docker イメージをカスタマイズする方法

Dockerfile を使用したイメージのカスタマイズイメージのカスタマイズとは、実際には各レイヤー...

Vue.jsはシンプルなタイマー機能を実装します

この記事では、参考までに、簡単なタイマー機能を実装するためのvue.jsの具体的なコードを紹介します...

非常に詳細な MySQL8.0.22 のインストールと設定のチュートリアル

みなさんこんにちは。今日は、MySQL 8.0.22 のインストールと構成について学習します。注意深...

ServerSocketのデフォルトIPバインディングの実装プロセスの詳細な説明

開発中にサーバーを起動する必要がある場合、ローカルテストではポートを直接書き込み、実際の環境ではバイ...

SQL 結合クエリの内部結合、外部結合、クロス結合の違いの詳細な説明

データベースを使用するアプリケーションを開発する場合、必然的にユニオンクエリを使用する必要があります...

Vueでデータを読み取るためにこれを悪用しないでください

目次序文1. これを使用してデータ内のデータを読み取るプロセス2. Dep.target はいつ存在...

MySQL 8で追加された3つの新しいインデックスは、非表示、降順、関数です。

目次MySQL 8 の隠しインデックス、降順インデックス、関数インデックス1. 隠しインデックス1....