Карты против объектов в ES6, когда использовать?


Ref: MDN Maps

используйте карты над объектами, когда ключи неизвестны до времени выполнения, и когда все ключи имеют один и тот же тип, и все значения имеют один и тот же тип.

используйте объекты, когда есть логика, которая работает на отдельных элементах.

вопрос:

каков применимый пример использования карт над объектами? в частности, "когда ключи будут неизвестны пока время выполнения?"

var myMap = new Map();

var keyObj = {},
    keyFunc = function () { return 'hey'},
    keyString = "a string";

// setting the values
myMap.set(keyString, "value associated with 'a string'");
myMap.set(keyObj, "value associated with keyObj");
myMap.set(keyFunc, "value associated with keyFunc");

console.log(myMap.get(keyFunc));
5 67

5 ответов:

каков применимый пример использования карт над объектами?

Я думаю, что вы уже дали один хороший пример: вам как минимум нужно использовать Maps при использовании объектов (включая объекты, функции) в качестве ключей.

в частности, "когда ключи будут неизвестно до времени выполнения?"

всякий раз, когда они не известны во время компиляции. Короче говоря, вы всегда должны использовать Map когда вам нужно

Я думаю, что с ES2015 в Map для использования простых объектов осталось только две причины:

когда порядок собственности не имеет значения?

  • если у вас есть только одно значение, и некоторые функции, которые должен быть явно связан с ним (например Promise - который является прокси для будущего значения-и then/catch)
  • если у вас есть структура/запись-подобная структура данных со статическим набором свойств, известных во время "компиляции" (обычно структуры/записи не повторяются)

во всех других случаях вы можете рассмотреть возможность использования Map, потому что он сохраняет порядок свойств и отделяет программу (все свойства, присвоенные Map объект) с уровня данных (все записи в ).

каковы недостатки Map?

  • вы теряете краткий объект литеральный синтаксис
  • вам нужны пользовательские заменители для JSON.stringyfy
  • вы теряете деструктурирование, что в любом случае более полезно для статических структур данных

используйте карты над объектами, когда ключи неизвестны до времени выполнения, и когда все ключи одного типа и все значения одного типа.

Я понятия не имею, почему кто-то написал что-то настолько очевидно неправильное. Я должен сказать, что люди находят все больше и больше неправильного и/или сомнительного контента на MDN в эти дни.

в этом предложении нет ничего правильного. Основная причина использования карт заключается в том, что вам нужны объектно-значные ключи. Мысль о том, что ценности должны быть одним и тем же типом абсурдно-хотя они могут быть, конечно. Идея о том, что не следует использовать объекты, когда ключи неизвестны до времени выполнения, одинаково абсурдна.

этот вопрос является дубликатом но пока он не закрыт, вот мой ответ оттуда:

в дополнение к другим ответам, я обнаружил, что карты более громоздкие и подробные для работы, чем объекты.

obj[key] += x
// vs.
map.set(map.get(key) + x)

это важно, потому что более короткий код быстрее читается, более непосредственно выразителен и лучше хранится в голове программиста.

еще один аспект: потому что set () возвращает карту, не значение, это невозможно цепочка назначений.

foo = obj[key] = x;  // Does what you expect
foo = map.set(key, x)  // foo !== x; foo === map

отладка карт также более болезненна. Ниже вы не можете увидеть, какие ключи находятся на карте. Для этого вам придется написать код.

Good luck evaluating a Map Iterator

объекты могут быть оценены любой IDE:

WebStorm evaluating an object

одно из различий между Map и Object - это:

Map может использовать сложный тип данных в качестве ключа. вот так:

const fn = function() {}
const m = new Map([[document.body, 'stackoverflow'], [fn, 'redis']]);

m.get(document.body) // 'stackoverflow'
m.get(fn) //'redis'

осторожно: для сложного типа данных, Если вы хотите получить значение, вы должны передать ту же ссылку, что и ключ.

Object, он принимает только простой тип данных (number,string) в качестве ключа.

const a = {};
a[document.body] = 'stackoverflow';

console.log(a) //{[object HTMLBodyElement]: "stackoverflow"}