Карты против объектов в ES6, когда использовать?
Используйте карты над объектами, когда ключи неизвестны до времени выполнения, и когда все ключи имеют одинаковый тип и все значения имеют одинаковый тип.
Используйте объекты, когда есть логика, которая работает с отдельными элементами.
Вопрос:
Что является применимым примером использования Карт над объектами? в частности, "когда ключи будут неизвестны до времени выполнения?"
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 ответов
Что является применимым примером использования Карт над объектами?
Я думаю, что вы уже дали один хороший пример: по крайней мере, вам нужно использовать Map
s, когда вы используете объекты (включая объекты Function) в качестве ключей.
в частности, "когда ключи будут неизвестны до времени выполнения?"
Всякий раз, когда они не известны во время компиляции. Короче говоря, вы всегда должны использовать Map
когда вам нужна коллекция ключ-значение. Хороший индикатор того, что вам нужна коллекция, - это когда вы динамически добавляете и удаляете значения из коллекции, особенно если вы заранее не знаете эти значения (например, они считываются из базы данных, вводятся пользователем и т. Д.).
Напротив, вы должны использовать объекты, когда вы знаете, какие свойства и у какого объекта есть при написании кода - когда их форма статична. Как сказал @Felix: когда вам нужна запись. Хороший индикатор для того, чтобы это нужно, - это когда поля имеют разные типы, и когда вам никогда не нужно использовать скобочную запись (или ожидать ограниченного набора имен свойств в ней).
Я думаю, что с ES2015 Map
осталось только две причины использовать простые объекты:
- Вы вообще не хотите перебирать свойства типа объекта
- или вы делаете, но порядок свойств не имеет значения, и вы можете отличить программу от уровня данных при итерации
Когда порядок собственности не важен?
- если у вас есть только одно значение и некоторые функции, которые должны быть явно связаны с ним (например,
Promise
- который является прокси для будущей стоимости - иthen
/catch
) - если у вас есть структура данных, похожая на структуру / запись со статическим набором свойств, известных во время компиляции (обычно структуры / записи не повторяются)
Во всех других случаях вы можете рассмотреть возможность использования Map
потому что он сохраняет порядок свойств и разделяет программу (все свойства, назначенные Map
объект) из уровня данных (все записи в Map
сам).
Каковы недостатки Map
?
- вы теряете краткий объект буквальный синтаксис
- вам нужны пользовательские заменители для JSON.stringyfy
- вы теряете деструктуризацию, которая в любом случае более полезна для статических структур данных
Используйте карты над объектами, когда ключи неизвестны до времени выполнения, и когда все ключи имеют одинаковый тип и все значения имеют одинаковый тип.
Я понятия не имею, почему кто-то написал бы что-то так явно неправильно. Я должен сказать, что в наши дни люди все чаще находят неправильный и / или сомнительный контент на MDN.
Ничто в этом предложении не является правильным. Основная причина использования карт - когда вам нужны ключи с объектными значениями. Идея о том, что значения должны быть одного типа, абсурдна, хотя, конечно, они могут быть. Идея, что не следует использовать объекты, когда ключи неизвестны до времени выполнения, в равной степени абсурдна.
Object
схожи с Map
В том, что оба позволяют вам устанавливать ключи к значениям, извлекать эти значения, удалять ключи и определять, хранится ли что-то в ключе. Из-за этого (и потому что не было никаких встроенных альтернатив), Object
s были использованы как Map
исторически; Однако есть важные различия, которые делают использование Map
предпочтительнее в определенных случаях:
- Ключи
Object
являютсяString
с иSymbol
s, тогда как они могут иметь любое значение дляMap
, включая функции, объекты и любые примитивы. - Ключи в
Map
упорядочены, а ключи, добавленные к объекту, - нет. Таким образом, при перебореMap
Объект возвращает ключи в порядке вставки. - Вы можете получить размер
Map
легко сsize
свойство, в то время как количество свойств вObject
должны быть определены вручную. Map
является итеративным и, таким образом, может быть непосредственно итерирован, тогда как итерация поObject
требует получения ключей каким-либо образом и итерации по ним.Object
имеет прототип, поэтому на карте есть ключи по умолчанию, которые могут столкнуться с вашими ключами, если вы не будете осторожны. Начиная с ES5 это можно обойти, используяmap = Object.create(null)
, но это редко делается.Map
может работать лучше в сценариях, включающих частое добавление и удаление пар ключей.
Одно из различий между Map
а также Object
является:
Map
может использовать сложный тип данных в качестве своего ключа. как это:
const fn = function() {}
const m = new Map([[document.body, 'stackru'], [fn, 'redis']]);
m.get(document.body) // 'stackru'
m.get(fn) //'redis'
обратите внимание: для сложного типа данных, если вы хотите получить значение, вы должны передать ту же ссылку, что и ключ.
Object
, он принимает только простой тип данных (number
, string
) как его ключ.
const a = {};
a[document.body] = 'stackru';
console.log(a) //{[object HTMLBodyElement]: "stackru"}
Этот вопрос является дубликатом но пока он не закрыт, вот мой ответ оттуда:
В дополнение к другим ответам я обнаружил, что Карты более громоздкие и многословные для работы, чем объекты.
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
Отладка карт также более болезненна. Ниже вы не можете увидеть, какие ключи на карте. Вы должны написать код, чтобы сделать это.
Объекты могут быть оценены любой IDE: