Карты против объектов в ES6, когда использовать?
Ссылка: Карты MDN
Используйте карты над объектами, когда ключи неизвестны до времени выполнения, и когда все ключи одного типа, и все значения одного типа.
Использовать объекты, когда существует логика, которая работает с отдельными элементами.
Вопрос:
Какой применимый пример использования Карт над объектами? в частности, "когда ключи будут неизвестны до времени выполнения?"
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));
Ответы
Ответ 1
Что такое применимый пример использования Карт над объектами?
Я думаю, что вы уже дали один хороший пример: вам, по крайней мере, нужно использовать Map
, когда вы используете объекты (включая объекты функций) в качестве ключей.
в частности, "когда ключи будут неизвестны до выполнения?"
Всякий раз, когда они не известны во время компиляции. Короче говоря, вы всегда должны использовать Map
, когда вам нужна коллекция значений ключа. Хорошим индикатором того, что вам нужна коллекция, является динамическое добавление и удаление значений из коллекции, особенно если вы заранее не знаете эти значения (например, они считываются из базы данных, вводятся пользователем и т.д.).
Напротив, вы должны использовать объекты, когда знаете, какие и сколько свойств имеет объект при написании кода, - когда их форма статична. Как сказал @Felix: когда вам нужен record. Хорошим показателем для этого является то, когда поля имеют разные типы, и когда вам никогда не нужно использовать скобку (или ожидать ограниченный набор имен свойств в ней).
Ответ 2
Я думаю, что в ES2015 Map
осталось только две причины использовать простые объекты:
.Когда порядок собственности не важен?
- если у вас есть только одно значение и некоторые функции, которые должны быть явно связаны с ним (например,
Promise
- который является прокси для будущего значения - и then
/catch
)
- если у вас есть структура данных, похожая на структуру/запись со статическим набором свойств, известных во время компиляции (обычно структуры/записи не повторяемы)
Во всех других случаях вы можете рассмотреть возможность использования Map
, поскольку он сохраняет порядок свойств и отделяет программу (все свойства, назначенные объекту Map
) от уровня данных (все записи в самом Map
).
Каковы недостатки Map
?
- вы теряете краткий объектный буквальный синтаксис
- вам нужны пользовательские заменители для JSON.stringyfy
- вы теряете деструктуризацию, которая в любом случае более полезна для статических структур данных
Ответ 3
Используйте карты над объектами, когда ключи неизвестны до времени выполнения, и когда все ключи одного типа, и все значения одного типа.
Я понятия не имею, почему кто-то написал что-то настолько явно неправильное. Я должен сказать, что люди находят все больше и больше неправильного и/или сомнительного контента на MDN в эти дни.
Ничто в этом предложении не является правильным. Основной причиной использования карт является то, что вы хотите использовать объектно-ориентированные ключи. Идея о том, что ценности должны быть одного и того же типа, абсурдна - хотя они могут быть, конечно. Идея о том, что нельзя использовать объекты, когда ключи неизвестны до тех пор, пока время выполнения не станет абсурдным.
Ответ 4
Одно из отличий между 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"}
Ответ 5
Этот вопрос является дубликатом , но до его закрытия здесь мой ответ оттуда:
В дополнение к другим ответам, я обнаружил, что Карты более громоздки и многословны для работы с объектами.
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:
![WebStorm, оценивающий объект]()
Ответ 6
Object
похожи на Map
в том, что оба позволяют вам устанавливать ключи к значениям, извлекать эти значения, удалять ключи и определять, сохраняется ли что-то в ключе. Из-за этого (и потому что не было встроенных альтернатив), Object
исторически использовался как Map
; однако существуют важные различия, которые делают использование Map
предпочтительным в некоторых случаях:
- Клавиши
Object
- это String
и Symbol
, тогда как они могут быть
любое значение для Map
, включая функции, объекты и любой примитив.
- Ключи в
Map
упорядочены, а ключи, добавленные к объекту, не упорядочены. Таким образом,
при выполнении итерации объект Map
возвращает ключи в порядке
вставки.
- Вы можете легко получить размер
Map
с помощью свойства size
, в то время как
количество свойств в Object
должно быть определено вручную.
Map
является итеративным и, таким образом, может быть напрямую повторен, тогда как
перебор Object
требует некоторого способа получить его ключи
и перебирая их.
- У
Object
есть прототип, поэтому на карте есть ключи по умолчанию, которые
может столкнуться с вашими ключами, если вы не будете осторожны. Начиная с ES5 это
можно обойти с помощью map = Object.create(null)
, но это
редко делается.
Map
может работать лучше в сценариях, включающих частое добавление и
удаление пар ключей.
MDN