<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0"><channel><title><![CDATA[Chrome 145: Map.getOrInsert для атомарных операций]]></title><description><![CDATA[<p dir="auto">В Chrome 145 появился долгожданный метод <code>getOrInsert()</code> для объектов Map и WeakMap. Это не просто новая фишка - это решение реальной проблемы, с которой сталкиваются разработчики при работе с коллекциями. Метод позволяет получить значение по ключу или вставить новое значение за одну операцию, минуя лишние проверки.</p>
<p dir="auto">Это особенно полезно, когда вам нужно гарантировать наличие значения в объекте перед тем, как с ним работать. Вместо трёх строк кода теперь хватает одной - проще, безопаснее и эффективнее. Давайте разберёмся, как это работает и почему это важно для современной разработки.</p>
<h2>Что такое getOrInsert и зачем он нужен</h2>
<p dir="auto">В традиционном подходе, чтобы получить значение из Map или установить его по умолчанию, приходилось писать проверку вручную. Вы проверяли наличие ключа через <code>has()</code>, потом либо получали значение через <code>get()</code>, либо устанавливали новое через <code>set()</code>. Это работает, но требует больше кода и оставляет место для ошибок.</p>
<p dir="auto">Метод <code>getOrInsert()</code> объединяет эти операции в одну атомарную операцию. Если ключ существует - вернёт его значение. Если нет - установит переданное значение по умолчанию и вернёт его. Всё просто и понятно. На практике это означает, что вы избегаете race-условий в асинхронном коде и пишете менее громоздкий код.</p>
<p dir="auto">Вот как выглядел старый способ:</p>
<pre><code class="language-javascript">const map = new Map();
let value;

if (map.has('key')) {
  value = map.get('key');
} else {
  value = 'default';
  map.set('key', value);
}
</code></pre>
<p dir="auto">Теперь то же самое в одной строке:</p>
<pre><code class="language-javascript">const value = map.getOrInsert('key', 'default');
</code></pre>
<p dir="auto">Разница очевидна - кода меньше, логики понятнее, и меньше шансов что-то упустить.</p>
<h2>Практические примеры использования</h2>
<p dir="auto">Частый сценарий - работа с кешем или пулом значений. Представьте, что у вас есть Map, где каждому пользователю соответствует массив событий. Вам нужно добавить новое событие, но если массива для этого пользователя ещё не существует, создать его.</p>
<p dir="auto">Раньше это выглядело так:</p>
<pre><code class="language-javascript">const userEvents = new Map();
const userId = 123;
const newEvent = { type: 'login', time: Date.now() };

if (!userEvents.has(userId)) {
  userEvents.set(userId, []);
}
userEvents.get(userId).push(newEvent);
</code></pre>
<p dir="auto">С <code>getOrInsert()</code> становится проще:</p>
<pre><code class="language-javascript">const userEvents = new Map();
const userId = 123;
const newEvent = { type: 'login', time: Date.now() };

userEvents.getOrInsert(userId, []).push(newEvent);
</code></pre>
<p dir="auto">Ещё один полезный пример - инициализация конфигураций с дефолтными значениями. Это особенно актуально, когда вы нормализуете пользовательский ввод:</p>
<pre><code class="language-javascript">const config = readUserConfig();
config.getOrInsert('theme', 'light');
config.getOrInsert('fontSize', 14);
config.getOrInsert('notifications', true);

// Теперь безопасно работаете с этими значениями
document.body.dataset.theme = config.get('theme');
</code></pre>
<p dir="auto">Это избегает потребности в многократных проверках <code>has()</code> перед каждым <code>get()</code>.</p>
<h2>Два варианта: getOrInsert и getOrInsertComputed</h2>
<p dir="auto">Помимо базового <code>getOrInsert()</code>, в спецификацию добавлен и <code>getOrInsertComputed()</code>. В чём разница? Первый принимает готовое значение, второй - функцию, которая вычисляет значение только если оно действительно понадобилось.</p>
<p dir="auto">Это критично для производительности, когда вычисление дефолтного значения дорого. Не имеет смысла вычислять сложное значение, если ключ уже существует в Map. Давайте сравним:</p>
<table class="table table-bordered table-striped">
<thead>
<tr>
<th>Метод</th>
<th>Параметр</th>
<th>Когда использовать</th>
<th>Преимущество</th>
</tr>
</thead>
<tbody>
<tr>
<td>getOrInsert()</td>
<td>Готовое значение</td>
<td>Простые значения (строки, числа)</td>
<td>Прямолинейный код</td>
</tr>
<tr>
<td>getOrInsertComputed()</td>
<td>Функция-колбэк</td>
<td>Дорогие вычисления (API запросы, парсинг)</td>
<td>Экономит ресурсы</td>
</tr>
</tbody>
</table>
<p dir="auto">Пример использования <code>getOrInsertComputed()</code>:</p>
<pre><code class="language-javascript">const cache = new Map();

// Функция вычисляется только если ключа нет
const result = cache.getOrInsertComputed('expensive-key', () =&gt; {
  return someExpensiveOperation();
});
</code></pre>
<p dir="auto">Здесь <code>someExpensiveOperation()</code> вызовется только когда ключа точно не существует в Map. Если ключ есть - функция никогда не выполнится.</p>
<h2>Поддержка браузерами и текущий статус</h2>
<p dir="auto">Метод был впервые реализован в Chrome 145, но поддержка разная в разных браузерах. На момент 2026 года статус такой:</p>
<ul>
<li><strong>Chrome 145+</strong>: полная поддержка</li>
<li><strong>Firefox 144+</strong>: полная поддержка</li>
<li><strong>Safari 26.2+</strong>: полная поддержка</li>
<li><strong>Edge</strong>: статус неясен, вероятно, впоследствии добавится</li>
<li><strong>Старые версии всех браузеров</strong>: не поддерживают</li>
</ul>
<p dir="auto">Если вам нужна поддержка старых браузеров, придётся писать полифил или использовать классический подход с проверками. Но для современных проектов, нацеленных на свежие версии браузеров, это уже доступное решение.</p>
<p dir="auto">Механизм работает одинаково для обычных Map и для WeakMap - с той лишь оговоркой, что WeakMap хранит слабые ссылки на объекты-ключи.</p>
<h2>Как это влияет на качество кода</h2>
<p dir="auto">Во-первых, <strong>меньше ошибок</strong>. Вы не случайно забудете проверить наличие ключа, потому что логика встроена в метод. Во-вторых, <strong>читаемость кода</strong>. Когда вы видите <code>getOrInsert()</code>, сразу понятно, что происходит - не нужно анализировать условия и цепочку операций.</p>
<p dir="auto">В-третьих, это <strong>лучшая производительность</strong> в многопоточной среде (при использовании Web Workers). Атомарность операции предотвращает гонку условий, где два потока могут одновременно попытаться установить значение для одного ключа.</p>
<p dir="auto">В-четвёртых, это <strong>стандарт ECMAScript</strong>, а не какой-то фреймворк или библиотека. Значит, вы полагаетесь на проверенный и оптимизированный движком код, а не самописный вспомогательный код.</p>
<p dir="auto">Список преимуществ <code>getOrInsert()</code> в контексте современной разработки:</p>
<ul>
<li>Избегаете трёхстрочных конструкций <code>if-has-set-get</code></li>
<li>Гарантируете безопасность в асинхронном коде</li>
<li>Экономите память благодаря ленивым вычислениям (через <code>getOrInsertComputed</code>)</li>
<li>Пишете код в соответствии с ECMAScript стандартом</li>
<li>Упрощаете тестирование и отладку логики с Map</li>
</ul>
<h2>Что осталось за кадром</h2>
<p dir="auto">Метод <code>getOrInsert()</code> - это хороший пример того, как стандарты эволюционируют на основе потребностей разработчиков. Долгое время это было частой критикой JavaScript - что для простых операций нужно писать много кода. Теперь эта боль постепенно уходит.</p>
<p dir="auto">Если вы работаете с новыми версиями браузеров или серверным JavaScript (Node.js), обязательно добавьте <code>getOrInsert()</code> в свой арсенал. Это один из тех инструментов, которые кажутся мелкой фишкой, но в большом проекте существенно упрощают жизнь и снижают количество багов. Стоит переглянуть старый код и найти места, где эта операция была бы полезнее классического подхода.</p>
]]></description><link>https://forum.exlends.ru/topic/1524/chrome-145-map.getorinsert-dlya-atomarnyh-operacij</link><generator>RSS for Node</generator><lastBuildDate>Sat, 17 Oct 2026 02:57:02 GMT</lastBuildDate><atom:link href="https://forum.exlends.ru/topic/1524.rss" rel="self" type="application/rss+xml"/><pubDate>Tue, 10 Mar 2026 05:36:40 GMT</pubDate><ttl>60</ttl></channel></rss>