Map() становится удобнее
07.12.2025 • js
Как пишем сейчас
Я думаю, многие узнают свой код в следующих строчках:
let list;
if (map.has(key)) {
list = map.get(key);
} else {
list = [];
map.set(key, list);
}
list.push(value);Каждый раз, когда приходится его писать, у меня в голове мысль:
Почему так много строк на абсолютно простую и понятную конструкцию? Почему нельзя проще?
И это ещё без возможных ошибок тайпинга. Вот если бы был другой способ написать этот код…
2025 (да, уже)
Новый способ:
map.getOrInsert(key, []).push(value);Да, вот так просто. Именно так, как оно и должно было быть изначально. Метод getOrInsert очень похож на set, только не осуществляет вставку, если такой ключ уже есть. А ещё он возвращает значение, как get, но мы всегда можем быть уверены, что это значение будет.
Ещё один пример, если нам тут же нужно не только получить значение, но и обновить его в случае существования:
// Старый вариант
let counter = map.get(key) || 0;
++counter;
map.set(key, counter);
// Новый вариант
map.set(key, map.getOrInsert(key, 0) + 1);Не сказать, что есть радикальная разница, но немного короче.
Хороший вопрос, что делать, если у нас сложные вычисления?
map.getOrInsert(key, complexCalculation());В этом случае эти вычисления будут выполнены, даже если ключ уже есть в map. На этот случай есть getOrInsertComputed:
map.getOrInsertComputed(key, key) => complexCalculation(key));Оба новых метода также доступны и на WeakMap.
Какой статус?
Предложение находится на Stage 3. И уже реализовано в 3х браузерах: Firefox, Chrome, Safari (пока что только девелоперские версии, в стабильных будет чуть позже).
В core-js поддержка появилась несколько месяцев назад, да и полифилятся новые методы элементарно.
Map.prototype.getOrInsert = function (key, defaultValue) {
if (!this.has(key)) {
this.set(key, defaultValue);
}
return this.get(key);
};
Map.prototype.getOrInsertComputed = function (key, callbackFunction) {
if (!this.has(key)) {
this.set(key, callbackFunction(key));
}
return this.get(key);
};