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

推薦する

Vueデータ監視の原理の詳細な説明

目次1. はじめにII. 監視対象2.1 なぜオブジェクトを監視する必要があるのですか? 2.2 デ...

Vue 名前付きスロットの基本的な使用例

序文名前付きスロットは、スロット内の「name」属性を使用して要素にバインドされます。知らせ: 1....

静的リソースファイルのアクセスログをフィルタリングするNginxの実装

乱雑なログ日常的に使用される Nginx は、静的リソース サーバーとリバース プロキシ サーバーの...

JavaScript でシンプルな Web 時計を実装する

JavaScript を使用して Web ページ クロックを実装します。効果は次の図に示されています...

Vueのカスタムディレクティブの詳細なガイド

目次1. カスタム指示とは何ですか? 2. 指示をカスタマイズする方法フック機能3. 応用シナリオ入...

フロントエンド開発における一般的なテクニックのまとめ

1. 記事タイトルリストの右側に日付を表​​示する方法:コードをコピーコードは次のとおりです。 &l...

Docker はクラスター MongoDB 実装手順を構築します

序文会社の業務上のニーズにより、独自の MongoDB サービスを構築する予定です。MongoDB ...

dl、dt、dd はいつ使用するのが適切ですか?

dl:定義一覧定義リストdt:定義タイトルタイトルを定義するdd:定義説明定義の説明dt は情報のタ...

MySQLの分離レベルとロックメカニズムの詳細な説明

目次簡単な説明: 1. 取引の4つの特徴2. 複数の同時トランザクションによって発生する問題3. ト...

MySQL 圧縮パッケージ版 zip インストール設定方法

圧縮版の記事ではデータの初期化がされていないなどいくつか問題があったため、Windows にインスト...

MySQL スケジュール データベース バックアップ (フル データベース バックアップ) の実装

目次1. MySQLデータのバックアップ1.1. データをバックアップするためのmysqldumpコ...

docker を使用してコード サーバーをデプロイする方法

画像をプルする # docker pull codercom/code-server # Docke...

Linuxのアラーム機能の例の説明

Linuxアラーム機能の紹介上記のコード: #include <stdio.h> #in...

Taobao の商品画像切り替え効果を実現する JavaScript

JavaScriptの服装アルバム切り替え効果(Taobao商品画像切り替えに似ています)、参考ま...

写真とテキストによる MySQL 8.0.21 インストール チュートリアル

1. ダウンロードリンクをダウンロードするダウンロードをクリックします。Oracle アカウントにロ...