純粋なJavaScriptオブジェクトの代わりにmapを使う

6819 ワード

作者:Dmitri Pavlutin
狂おしい技術家
原文:https://dmitripavlutin.com/ma...
無断転載は厳禁です.
JavaScript一般オブジェクト{key: 'value'}は、構造化データを保存するために使用されてもよい.
しかし、面倒くさいことに気づきました.対象のキーは文字列でなければなりません.
数字でキーを作ったらどうなりますか?この場合にはエラーはありません.
const names = {
  1: 'One',
  2: 'Two',
};

Object.keys(names); // => ['1', '2']
JavaScriptは、オブジェクトのキーを隠し文字列に変換するだけです.これは苦手なことです.タイプの整合性を失ってしまいました.
本論文では、キーを文字列に変換することを含む、ES 2015に提供されるJavaScript Mapオブジェクトの多くの一般的なオブジェクトの問題を解決する方法を紹介します.
1.mapは任意の種類のキーを受け入れることができます.
上述したように、オブジェクトのキーが文字列または記号でない場合、JavaScriptは、その隠しキーを文字列に変換します.
ラッキーなことに、mapはキータイプに問題がないです.
const numbersMap = new Map();

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

[...numbersMap.keys()]; // => [1, 2]
1および2numbersMapのキーである.これらのキーのタイプはnumberに変わりません.
mapでは任意のキータイプを使用できます.数字、ブール、および古典的な文字列と記号です.
const booleansMap = new Map();

booleansMap.set(true, "Yep");
booleansMap.set(false, "Nope");

[...booleansMap.keys()]; // => [true, false]
booleansMapは、ブール値をキーとして使っても大丈夫です.
同様に、ブールキーは通常のオブジェクトでは機能しません.
限界を超えましょう.対象全体をmapのキーとして使ってもいいですか?もちろんいいです
1.1オブジェクトをキーにする
オブジェクトに関するデータを格納する必要があると仮定しますが、これらのデータはオブジェクト自体に付加されません.
普通の相手ではできません.
1つの解決方法は、オブジェクトの値のグループを使用します.
const foo = { name: 'foo' };
const bar = { name: 'bar' };

const kindOfMap = [
  [foo, 'Foo related data'],
  [bar, 'Bar related data'],
];
kindOfMapは、一対のオブジェクトと関連値を含む配列である.
この方法の最大の問題は,結合による値へのアクセス時間の複雑さがO(n)であることである.配列全体を巡回してこそ、キーで必要な値が得られます.
function getByKey(kindOfMap, key) {
  for (const [k, v] of kindOfMap) {
    if (key === k) {
      return v;
    }
  }
  return undefined;
}

getByKey(kindOfMap, foo); // => 'Foo related data'
WeakMap(Map専用バージョン)を使って、お悩みになる必要はありません.オブジェクトをキーとして受け入れる.MapWeakMapの間の主な違いは、後者がキーとなるオブジェクトのゴミ回収を許可し、メモリ漏れを防止することである.
上記のコードをWeakMapのコードを使用して支払うために再構成することの代価は微々たるものである.
const foo = { name: 'foo' };
const bar = { name: 'bar' };

const mapOfObjects = new WeakMap();

mapOfObjects.set(foo, 'Foo related data');
mapOfObjects.set(bar, 'Bar related data');

mapOfObjects.get(foo); // => 'Foo related data'
Mapに対して、WeakMapは、オブジェクトだけをキーとして受け入れ、簡略化された方法セットを有する.
2.mapはキー名に制限がない
JavaScriptのいずれのオブジェクトもその原型オブジェクトから属性を継承します.普通のJavaScriptの対象も同じです.
プロトタイプから継承された属性をカバーすると、これらのプロトタイプ属性に依存するコードが破壊される可能性があります.
function isPlainObject(value) {
  return value.toString() === '[object Object]';
}

const actor = {
  name: 'Harrison Ford',
  toString: 'Actor: Harrison Ford'
};

// Does not work!
isPlainObject(actor); // TypeError: value.toString is not a function
オブジェクトactorに定義された属性toStringは、プロトタイプから継承されるtoString()方法をカバーする.toString()方法に依存しているので、これはisObject()を破壊した.
通常のオブジェクトが原型から継承される属性と方法のリストを確認します.これらの名前を使用してカスタム属性を定義しないようにします.
例えば、特定のカスタムフィールドを管理するユーザーインターフェースがあると仮定する.ユーザーは名前と値を指定してフィールドを追加できます.
カスタムフィールドの状態を通常のオブジェクトに保存すると便利です.
const userCustomFields = {
  'color':    'blue',
  'size':     'medium',
  'toString': 'A blue box'
};
しかし、ユーザーは、たとえばtoStringconstructorなどのカスタムフィールド名を選択することができます.これは、オブジェクトを破壊する可能性があります.
ユーザーの入力を受けることで、通常のオブジェクトにキーを作成しないでください.
mapはこの問題がありません.キーの名前は制限されません.
function isMap(value) {
  return value.toString() === '[object Map]';
}

const actorMap = new Map();

actorMap.set('name', 'Harrison Ford');
actorMap.set('toString', 'Actor: Harrison Ford');

// Works!
isMap(actorMap); // => true
actorMaptoStringという属性を有しているかどうかにかかわらず、方法toString()は正常に動作する.
3.mapは反復可能です.
一般的なオブジェクトの属性を遍歴するためには、Object.keys()またはObject.entries()などの他の補助的な静的関数を使用しなければなりません.
const colorsHex = {
  'white': '#FFFFFF',
  'black': '#000000'
};

for (const [color, hex] of Object.entries(colorsHex)) {
  console.log(color, hex);
}
// 'white' '#FFFFFF'
// 'black' '#000000'
Object.entries(colorsHex)は、オブジェクトから抽出されたキーパッドの対配列を返す.
しかし、map自体は反復可能である:
const colorsHexMap = new Map();

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

for (const [color, hex] of colorsHexMap) {
  console.log(color, hex);
}
// 'white' '#FFFFFF'
// 'black' '#000000'
colorsHexMapは反復可能である.任意の反復可能な場所で使用できます.for()ループ、演算子[...map]などを展開します.
mapはまた、反復を返す他の方法を提供する.map.keys()は巡回キーであり、map.values()は巡回値である.
4.mapのサイズ
通常のオブジェクトのもう一つの問題は、あなたが持っている属性の数を簡単に確認できないことです.
const exams = {
  'John Smith': '10 points',
  'Jane Doe': '8 points',
};

Object.keys(exams).length; // => 2
examsのサイズを決定するには、そのすべてのキーによってその数を決定しなければなりません.
mapは、そのアクセス器属性sizeを介してキーのペアを計算する代替方法を提供する.
const examsMap = new Map([
  ['John Smith', '10 points'],
  ['Jane Doe', '8 points'],
]);
  
examsMap.size; // => 2
mapのサイズを決定することはより簡単である.examsMap.size.
5.結論
通常のJavaScriptオブジェクトは構造データをよく保存することができる.しかし、それらにはいくつかの制限があります.
  • は、文字列または記号のみをキーとして使用することができます.
  • 自身のオブジェクト属性は、プロトタイプから継承された属性キーと競合する可能性がある(例えば、toStringconstructorなど).
  • オブジェクトはキーとして使用できません.
    これらの問題はすべてmapで簡単に解決できます.そして、それらは、例えば、ディエバクタやサイズ検索の容易さなどの利点を提供する.
    mapを普通の対象の代替品としないで、補充と見なすべきです.
    mapが普通の相手に対する他のメリットを知っていますか?下にコメントを書いてください.
    この記事の最初のWeChat公式アカウント:フロントエンドのパイオニア
    QRコードをスキャンして公衆番号に注目してください.毎日新鮮な先端技術文章を送ります.
    このコラムの他の高賛記事を読み続けてください.
  • Shadow DOM v 1
  • を深く理解する.
  • 一歩教えます.WebVRでバーチャルリアリティーを実現します.
  • 13個の開発効率を向上させる現代CSSフレーム
  • クイックハンドオーバBootstraphue
  • JavaScriptエンジンはどのように働きますか?コールスタックからPromiseまでは知っておく必要があります.
  • Websocket実戦:NodeとReactの間でリアルタイム通信を行う
  • Gitに関する20の面接問題
  • Node.jsのconsolie.log
  • を深く解析します.
  • Node.jsは一体何ですか?
  • 分、Node.jsでAPIサーバ
  • を構築する.
  • Javascriptのオブジェクトコピー
  • プログラマは30歳前の月給は30 Kに達しませんでした.
  • 14の最も良いJavaScriptデータ可視化ライブラリ
  • 8個のフロントエンドへの最上位VS Code拡張プラグイン
  • Node.jsマルチスレッド完全ガイド
  • HTMLをPDFに変換する4つの案と
  • を実現する.
  • もっと多い文章…