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

推薦する

MySql データベース クエリの特殊コマンド

まずMySQLのインストールMySQLソフトウェアをダウンロードし、インストールパスを変更しますMy...

MySQL の Like の概念と使用法の説明

Like は中国語で「好き」を意味しますが、MySQL データベースに適用される場合、Like は、...

VueはElementUIのフォームサンプルコードを模倣する

実装要件ElementUI を模倣したフォームは、インデックス コンポーネント、Form フォーム ...

MySQLクエリ速度を最適化する方法

前の章では、高性能な MySQL に不可欠な、最適化されたデータ型の選択方法とインデックスの効率的な...

Docker の詳細なイラスト

1. Dockerの紹介1.1 仮想化1.1.1 仮想化とは何ですか?コンピュータにおける仮想化とは...

Docker デプロイメント MySQL8 クラスター (マスター 1 台とスレーブ 2 台) の実装手順

目次1. CentOS 7.9 20にDockerをインストールする2. MySQL クラスターをデ...

プロセスごとにネットワーク帯域幅を監視する Linux ツール Nethogs のインストールと展開

概要Linux 用のオープン ソース ネットワーク監視ツールは数多くあります。たとえば、帯域幅の使用...

Vue でのルーティングガードの具体的な使用法

目次1. グローバルガード1.1 グローバルフロントガード1.2 グローバルポストルートガード1.3...

Vue グローバルメソッドを設定する 2 つの方法

目次1. はじめに2. 最初の方法3. 2番目の方法要約する1. はじめにVue プロジェクトの開発...

CSSスクロールバーのスタイルをカスタマイズする方法の詳細な説明

この記事では、CSS スクロールバー セレクターを紹介し、Webkit ブラウザーと IE ブラウザ...

MySQL データベースの基礎: 基本コマンドの概要

目次1. ヘルプ情報を使用する2. データベースの作成、削除、表示3. データベースに接続する4. ...

Linux のパスワードを紛失した場合にリセットする方法

1. スタートアップメニューでは、カーソルを最初の行に移動します - eを押します 2. UTF-8...

知らないかもしれない実用的なTypeScriptのヒント

目次序文関数のオーバーロードマッピングタイプ部分的、読み取り専用、Null 可能、必須選択、記録除外...

React Diff Principle の詳細な分析

目次差分アルゴリズムレイヤーごとの比較同じタイプのコンポーネントを比較する同じタイプの要素の比較子ノ...

WeChatアプレットリクエストの前処理方法の詳細な説明

質問一部のページでは、onload でデータを要求してからビューをレンダリングするため、ミニプログラ...