<?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[Map.getOrInsert в ECMAScript 2026: атомарные операции для Map в Chrome 145]]></title><description><![CDATA[<p dir="auto">В ECMAScript 2026 появился метод <strong>Map.getOrInsert</strong>, который упрощает работу с коллекциями. Он возвращает значение по ключу или вставляет дефолтное, если ключа нет. Это решает проблему ручных проверок has/get/set, делая код короче и надежнее.</p>
<p dir="auto">Метод уже работает в <strong>Chrome 145</strong>, что удобно для фронтенда. Зачем это нужно? В реальных проектах часто группируют данные или инициализируют структуры - без лишнего boilerplate. Теперь один вызов заменяет три операции, снижая ошибки в многопоточных сценариях.</p>
<h2>Как работает Map.getOrInsert</h2>
<p dir="auto">Метод <strong>Map.prototype.getOrInsert(key, defaultValue)</strong> ищет ключ в Map. Если находит - возвращает значение. Если нет - вставляет пару key/defaultValue и возвращает defaultValue. Это атомарная операция по спецификации ECMAScript 2026.</p>
<p dir="auto">Логика простая: сравнивает ключи через SameValue, канонизирует их. Не создает лишних записей, работает быстро. В отличие от ручного if (map.has(key)) { return map.get(key); } map.set(key, defaultValue); - здесь все в одном вызове. Это особенно полезно при группировке данных или кэшировании.</p>
<p dir="auto">Пример: представь обработку логов, где по userId собираешь массив событий.</p>
<ul>
<li><strong>Базовый вызов:</strong></li>
</ul>
<pre><code class="language-javascript">const map = new Map();
const events = map.getOrInsert('user123', []);
events.push('login');
console.log(map.get('user123')); // ['login']
</code></pre>
<ul>
<li><strong>С дефолтным объектом:</strong></li>
</ul>
<pre><code class="language-javascript">const cache = new Map();
const config = cache.getOrInsert('app', { timeout: 5000 });
config.maxRetries = 3;
</code></pre>
<p dir="auto">Вот сравнение подходов:</p>
<table class="table table-bordered table-striped">
<thead>
<tr>
<th>Подход</th>
<th>Код</th>
<th>Плюсы</th>
<th>Минусы</th>
</tr>
</thead>
<tbody>
<tr>
<td>Ручной</td>
<td>if (!map.has(key)) map.set(key, []);</td>
<td>Полный контроль</td>
<td>3 вызова, race conditions</td>
</tr>
<tr>
<td>getOrInsert</td>
<td>map.getOrInsert(key, [])</td>
<td>Один вызов, атомарно</td>
<td>Только простые дефолты</td>
</tr>
<tr>
<td>?? оператор</td>
<td>map.set(key, map.get(key) ?? defaultValue)</td>
<td>Коротко</td>
<td>Не вставляет, если null/undefined валидны</td>
</tr>
</tbody>
</table>
<p dir="auto"><em>Важно:</em> Метод не вызывает колбэк всегда - только проверяет наличие.</p>
<h2>getOrInsertComputed для сложных случаев</h2>
<p dir="auto">Если дефолтное значение требует вычислений, используй <strong>Map.prototype.getOrInsertComputed(key, callback)</strong>. Колбэк вызывается только если ключа нет. Это экономит ресурсы - никаких лишних операций.</p>
<p dir="auto">Спецификация: сначала ищет ключ, если не находит - выполняет callback(key), затем вставляет и возвращает. Проверяет Map заново после колбэка на случай изменений. Идеально для дорогих инициализаций, как создание объектов или запросов.</p>
<p dir="auto">Пример группировки данных из API:</p>
<pre><code class="language-javascript">const grouped = new Map();
for (let item of data) {
  const list = grouped.getOrInsertComputed(item.category, () =&gt; new Set());
  list.add(item.id);
}
</code></pre>
<p dir="auto">Преимущества в списке:</p>
<ul>
<li>Вызов колбэка <em>только при необходимости</em> - оптимизация производительности.</li>
<li>Атомарность: даже если Map меняется в колбэке, логика устойчива.</li>
<li>Поддержка WeakMap - для временных объектов без утечек памяти.</li>
</ul>
<p dir="auto">Сравнение с getOrInsert:</p>
<table class="table table-bordered table-striped">
<thead>
<tr>
<th>Метод</th>
<th>Когда колбэк</th>
<th>Использование</th>
</tr>
</thead>
<tbody>
<tr>
<td>getOrInsert</td>
<td>Никогда</td>
<td>Простые константы: [] или {}</td>
</tr>
<tr>
<td>getOrInsertComputed</td>
<td>Если ключа нет</td>
<td>Сложные: new Proxy(), fetch()</td>
</tr>
</tbody>
</table>
<p dir="auto"><em>Нюанс:</em> callback получает key как аргумент, возвращает значение.</p>
<h2>Поддержка в Chrome 145 и других движках</h2>
<p dir="auto">В <strong>Chrome 145</strong> метод доступен полностью, включая WeakMap-варианты. Firefox с 144, Safari с 26.2 - браузеры 2026 года на борту. Это часть proposal-upsert от TC39, вошедшего в ECMAScript 2026.</p>
<p dir="auto">Проверить поддержку можно через CanIUse: Chrome 145+ - зеленый свет. Для полифиллов подойдет core-js, но в новых проектах не нужно. WeakMap.getOrInsert полезен для кэшей DOM-элементов - ключи удаляются с мусором.</p>
<p dir="auto">Ключевые фичи поддержки:</p>
<ul>
<li>Chrome 145: Map и WeakMap методы стабильны.</li>
<li>Edge 144+: частично, полная с 145.</li>
<li>Polyfill: !map.has(key) ? map.set(key, callback ? callback(key) : defaultValue) : map.get(key).</li>
</ul>
<p dir="auto"><em>Совет:</em> Тестируй в devtools - console.log(new Map().getOrInsert(‘test’, 42)) работает сразу.</p>
<h2>Атомарность и типичные сценарии</h2>
<p dir="auto"><strong>Map.getOrInsert</strong> гарантирует атомарность в single-threaded JS, но в Workers или с SharedArrayBuffer - осторожно с race conditions. Подходит для реактивных apps, где состояние мутирует часто.</p>
<p dir="auto">Рассмотрим сценарии: группировка в reducers, кэш конфигов, счетчики по ключам. Заменяет паттерны вроде map.get(key) ?? (map.set(key, defaultValue), defaultValue). Код чище, меньше багов с null/undefined.</p>
<p dir="auto">Примеры использования:</p>
<ul>
<li><strong>Группировка:</strong> map.getOrInsert(userId, []).push(event).</li>
<li><strong>Кэш:</strong> cache.getOrInsert(url, () =&gt; fetch(url).then(r =&gt; r.json()));</li>
<li><strong>Счетчики:</strong> stats.getOrInsert(action, 0)++;</li>
</ul>
<p dir="auto"><em>Ограничение:</em> Не для mutable defaultValue вроде [] - мутации видны всем.</p>
<h2>Новые горизонты для коллекций</h2>
<p dir="auto">Map.getOrInsert открывает двери для более declarative кода в JS. Остается внедрение в Node.js и полная кросс-браузерность. Стоит поэкспериментировать с WeakMap в garbage-collected структурах.</p>
<p dir="auto">Дальше - интеграция с Records/Tuples из будущих ECMA, где атомарность коллекций станет стандартом. Это шаг к более robust данным в веб-приложениях, без handmade оберток.</p>
]]></description><link>https://forum.exlends.com/topic/1560/map.getorinsert-v-ecmascript-2026-atomarnye-operacii-dlya-map-v-chrome-145</link><generator>RSS for Node</generator><lastBuildDate>Fri, 17 Apr 2026 11:08:14 GMT</lastBuildDate><atom:link href="https://forum.exlends.com/topic/1560.rss" rel="self" type="application/rss+xml"/><pubDate>Tue, 10 Mar 2026 11:43:05 GMT</pubDate><ttl>60</ttl></channel></rss>