Автор: Дмитрий Павлютин
Переводчик: Front-end Xiaozhi
Источник: дмитрипавлутин
Ставьте лайк и смотрите снова, формируйте привычку
эта статья
GitHub
GitHub.com/QQ449245884…Он был включен в вышеизложенное, и более ранние статьи с высокими похвалами были классифицированы, а также было систематизировано множество моих документов и учебных материалов. Добро пожаловать в Star and Perfect. Вы можете обратиться в тестовый центр для ознакомления во время собеседования. Надеюсь, у нас что-то получится вместе.
Простой объект JS{key: 'value'}
Используется для хранения структурированных данных. Но есть одна вещь, которая меня раздражает: ключи объектов должны быть строками (или редко используемымиsymbol
).
Что если цифры используются в качестве клавиш? В этом случае не будет ошибок:
const names = {
1: 'One',
2: 'Two',
};
Object.keys(names); // => ['1', '2']
JS неявно преобразует ключи объекта в строки, и это поведение по умолчанию теряет согласованность типов, и его сложно обойти. Но в ЕС6Map
Объекты могут помочь нам с такими проблемами, смотрите, смотрите, смотрите.
1. Карта принимает ключи любого типа
Как упоминалось ранее, если ключ объекта неstring
илиsymbol
, JS неявно преобразует его в строку.
К счастью,map
Проблем с типом ключа нет.
const numbersMap = new Map();
numbersMap.set(1, 'one');
numbersMap.set(2, 'two');
[...numbersMap.keys()]; // => [1, 2]
1
а также2
даnumbersMap
ключей в , тип (количество) этих ключей остается прежним.
допустимыйmpa
Используйте любой тип ключа: числовой, логический, строковый иsymbol
.
const booleansMap = new Map();
booleansMap.set(true, "Yep");
booleansMap.set(false, "Nope");
[...booleansMap.keys()]; // => [true, false]
booleansMap
использоватьbooleans
Как ключ без проблем. И наоборот, логические ключи не действуют на обычные объекты.
Прорвемся через воображение: использовать ли весь объект какmap
ключ, ответ: да.
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) может сделать это без особых проблем:он принимает объекты только как ключи.
Mapа такжеWeakmapОсновное различие между ними заключается в том,WeakmapПозволяет ключевым объектам собирать мусор, предотвращая утечки памяти.
Хорошо, используйте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. карта не имеет ограничений на имена ключей
Любой объект в JS наследует свойства объекта-прототипа, как и обычные объекты.
Переопределение свойств, унаследованных от прототипов, может привести к поломке кода, основанного на этих свойствах прототипа:
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
Свойства, определенные для акторов объектовtoString
Переопределить, унаследованное от прототипаtoString()
метод. это ломаетisObject()
, потому что это зависит отtoString()
метод.
Проверьте свойства, которые обычный объект наследует от прототипа исписок методов, избегайте определения пользовательских свойств с этими именами методов.
Например, предположим, что имеется пользовательский интерфейс, управляющий некоторыми настраиваемыми полями. Пользователи могут добавлять настраиваемые поля, указав имя и значение:
Было бы удобно хранить состояние пользовательского поля в обычном объекте:
const userCustomFields = {
'color': 'blue',
'size': 'medium',
'toString': 'A blue box'
};
Но пользователь может выбрать пользовательское имя поля, какtoString
(как в примере), конструкторы и т. д., которые могут уничтожить наши объекты.
Не используйте введенные пользователем значения в качестве ключей для обычных объектов.
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
Независимо от тогоactorMap
EстьtoString
характеристики,toString()
методы все работают нормально.
3. карта повторяема
Для обхода свойств обычных объектов необходимо использовать другие вспомогательные статические функции, такие как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. Размер карты
Другая проблема с обычным объектом заключается в том, что вы не можете сразу узнать количество свойств, которые он содержит.
const exams = {
'John Smith': '10 points',
'Jane Doe': '8 points',
};
Object.keys(exams).length; // => 2
чтобы быть увереннымexams
размера, необходимо передать все ключи, чтобы определить их количество.
map предоставляет свойство размера, которое представляет количество свойств.
const examsMap = new Map([
['John Smith', '10 points'],
['Jane Doe', '8 points'],
]);
examsMap.size; // => 2
Конечноmap
Количество свойств еще проще:examsMap.size
.
Суммировать
Простые JS-объекты, как правило, хорошо хранят структурированные данные, но они также имеют некоторые ограничения:
- В качестве ключей можно использовать только строки или символы.
- собственные свойства объекта могут конфликтовать с ключами свойств, унаследованными от прототипа (например,
toString
,constructor
Ждать). - Объект нельзя использовать в качестве ключа
Все эти вопросы можно пройтиmap
Легко исправить. Кроме того, они предоставляют такие преимущества, как итераторы и простой поиск размера.
Не делайтеmap
Как замену нормальному объекту, его следует рассматривать как дополнение к обычному объекту.
ты тоже знаешьmap
Есть ли другие преимущества перед обычными объектами?Оставьте комментарий ниже.
Ошибки, которые могут существовать после развертывания кода, не могут быть известны в режиме реального времени.Чтобы решить эти ошибки впоследствии, много времени тратится на отладку журнала.Кстати, я рекомендую всем полезный инструмент мониторинга ошибок.Fundebug.
оригинал:Рисовое путешествие avlutin.com/maps-vs-para…
общаться с
Статья постоянно обновляется каждую неделю. Вы можете выполнить поиск «Big Move to the World» в WeChat, чтобы прочитать и обновить ее как можно скорее (на одну или две статьи раньше, чем в блоге). Эта статья находится на GitHub.GitHub.com/QQ449245884…Он был включен, и многие мои документы были разобраны. Добро пожаловать в Звезду и совершенство. Вы можете обратиться в тестовый центр для ознакомления во время собеседования. Кроме того, обратите внимание на паблик-аккаунт и ответьте в фоновом режиме.Благосостояние, вы можете увидеть преимущества, вы знаете.