<?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 появилась поддержка метода <strong>Map.getOrInsert()</strong>. Это упрощает работу с коллекциями Map, где нужно быстро получать значение по ключу или вставлять значение по умолчанию, если ключа нет. Такой подход решает проблему race conditions в многопоточных сценариях и делает код чище.</p>
<p dir="auto">Метод полезен для кэшей, настроек пользователя или агрегации данных. Вместо проверок has() и set() вы пишете одну строку. Это экономит время и снижает ошибки в JavaScript-приложениях, особенно на фронтенде.</p>
<h2>Как работает Map.getOrInsert()</h2>
<p dir="auto">Метод <strong>Map.getOrInsert(key, defaultValue)</strong> возвращает значение по ключу, если оно есть, или вставляет и возвращает defaultValue. Это атомарная операция - нет промежуточных состояний, где Map может измениться другим потоком. Представьте кэш запросов: если ключ отсутствует, метод сам создаст пустой объект или массив.</p>
<p dir="auto">Пример: const map = new Map(); const value = map.getOrInsert(‘user’, {}); Теперь value - это объект, готовый к использованию. Без метода пришлось бы писать if (!map.has(‘user’)) map.set(‘user’, {}); return map.get(‘user’); Это на две строки больше и менее надежно.</p>
<p dir="auto">Раньше разработчики использовали паттерн map.get(key) ?? defaultValue, но он ненадежен, если null или undefined - валидные значения. getOrInsert решает это четко.</p>
<ul>
<li><strong>Атомарность</strong>: Метод гарантирует, что проверка и вставка происходят без прерываний.</li>
<li><strong>Производительность</strong>: Избегает двойного обращения к Map (has + get/set).</li>
<li><strong>Читаемость</strong>: Одна строка вместо трех - код становится короче и понятнее.</li>
</ul>
<table class="table table-bordered table-striped">
<thead>
<tr>
<th>Сравнение подходов</th>
<th>Старый способ</th>
<th>Map.getOrInsert()</th>
</tr>
</thead>
<tbody>
<tr>
<td><strong>Код</strong></td>
<td>if (!map.has(key)) map.set(key, def); return map.get(key);</td>
<td>map.getOrInsert(key, def)</td>
</tr>
<tr>
<td><strong>Строки</strong></td>
<td>3</td>
<td>1</td>
</tr>
<tr>
<td><strong>Атомарность</strong></td>
<td>Нет</td>
<td>Да</td>
</tr>
<tr>
<td><strong>Обработка null</strong></td>
<td>Проблемы</td>
<td>Без проблем</td>
</tr>
</tbody>
</table>
<h2>Map.getOrInsertComputed() для сложных случаев</h2>
<p dir="auto">Этот метод похож, но вместо фиксированного defaultValue принимает функцию. Функция вызывается только если ключа нет. Идеально, когда создание значения дорогое - например, вычисление или запрос к API.</p>
<p dir="auto">Синтаксис: map.getOrInsertComputed(key, () =&gt; expensiveComputation()). Если ключ есть, функция не запустится. Это как lazy initialization в других языках. Пример с массивом: map.getOrInsertComputed(‘logs’, () =&gt; []); Теперь можно сразу push без проверок.</p>
<p dir="auto">В реальных проектах это полезно для кэша вычислений. Допустим, вы агрегируете статистику пользователей - функция посчитает сумму только при первом обращении.</p>
<ul>
<li><strong>Ленивые вычисления</strong>: Функция выполняется только по необходимости.</li>
<li><strong>Аналог в WeakMap</strong>: WeakMap.getOrInsertComputed работает так же для слабых ссылок.</li>
<li><em>Нюанс</em>: Функция должна быть чистой - без сайд-эффектов, иначе поведение непредсказуемо.</li>
</ul>
<p dir="auto">Таблица преимуществ:</p>
<table class="table table-bordered table-striped">
<thead>
<tr>
<th>Сценарий</th>
<th>getOrInsert</th>
<th>getOrInsertComputed</th>
</tr>
</thead>
<tbody>
<tr>
<td><strong>Простой default</strong></td>
<td><img src="https://forum.exlends.ru/assets/plugins/nodebb-plugin-emoji/emoji/android/2705.png?v=a1e94250dac" class="not-responsive emoji emoji-android emoji--white_check_mark" style="height:23px;width:auto;vertical-align:middle" title="✅" alt="✅" /></td>
<td><img src="https://forum.exlends.ru/assets/plugins/nodebb-plugin-emoji/emoji/android/2705.png?v=a1e94250dac" class="not-responsive emoji emoji-android emoji--white_check_mark" style="height:23px;width:auto;vertical-align:middle" title="✅" alt="✅" /> (но избыточно)</td>
</tr>
<tr>
<td><strong>Дорогое значение</strong></td>
<td><img src="https://forum.exlends.ru/assets/plugins/nodebb-plugin-emoji/emoji/android/274c.png?v=a1e94250dac" class="not-responsive emoji emoji-android emoji--x" style="height:23px;width:auto;vertical-align:middle" title="❌" alt="❌" /></td>
<td><img src="https://forum.exlends.ru/assets/plugins/nodebb-plugin-emoji/emoji/android/2705.png?v=a1e94250dac" class="not-responsive emoji emoji-android emoji--white_check_mark" style="height:23px;width:auto;vertical-align:middle" title="✅" alt="✅" /></td>
</tr>
<tr>
<td><strong>Массивы/объекты</strong></td>
<td><img src="https://forum.exlends.ru/assets/plugins/nodebb-plugin-emoji/emoji/android/2705.png?v=a1e94250dac" class="not-responsive emoji emoji-android emoji--white_check_mark" style="height:23px;width:auto;vertical-align:middle" title="✅" alt="✅" /> map.getOrInsert(key, [])</td>
<td><img src="https://forum.exlends.ru/assets/plugins/nodebb-plugin-emoji/emoji/android/2705.png?v=a1e94250dac" class="not-responsive emoji emoji-android emoji--white_check_mark" style="height:23px;width:auto;vertical-align:middle" title="✅" alt="✅" /> С функцией</td>
</tr>
<tr>
<td><strong>WeakMap</strong></td>
<td><img src="https://forum.exlends.ru/assets/plugins/nodebb-plugin-emoji/emoji/android/2705.png?v=a1e94250dac" class="not-responsive emoji emoji-android emoji--white_check_mark" style="height:23px;width:auto;vertical-align:middle" title="✅" alt="✅" /></td>
<td><img src="https://forum.exlends.ru/assets/plugins/nodebb-plugin-emoji/emoji/android/2705.png?v=a1e94250dac" class="not-responsive emoji emoji-android emoji--white_check_mark" style="height:23px;width:auto;vertical-align:middle" title="✅" alt="✅" /></td>
</tr>
</tbody>
</table>
<h2>Поддержка в браузерах и полифиллы</h2>
<p dir="auto">Chrome 145 первым добавил <strong>getOrInsert</strong> для Map и WeakMap. Firefox с версии 144, Safari с 26.2. Edge пока отстает - до 143 не поддерживает. Для Android Chrome поддержка с 145.</p>
<p dir="auto">Проверить можно на <a href="http://caniuse.com" target="_blank" rel="noopener noreferrer">caniuse.com</a>: полная поддержка в новых версиях, но для старых IE/Edge нужен полифилл. Простой полифилл: Map.prototype.getOrInsert = function(key, def) { if (!this.has(key)) this.set(key, def); return this.get(key); };</p>
<p dir="auto">Это не атомарно, но лучше, чем ничего. В production проверяйте feature detection: if (‘getOrInsert’ in Map.prototype).</p>
<ul>
<li><strong>Chrome</strong>: 145+ <img src="https://forum.exlends.ru/assets/plugins/nodebb-plugin-emoji/emoji/android/2705.png?v=a1e94250dac" class="not-responsive emoji emoji-android emoji--white_check_mark" style="height:23px;width:auto;vertical-align:middle" title="✅" alt="✅" /></li>
<li><strong>Firefox</strong>: 144+ <img src="https://forum.exlends.ru/assets/plugins/nodebb-plugin-emoji/emoji/android/2705.png?v=a1e94250dac" class="not-responsive emoji emoji-android emoji--white_check_mark" style="height:23px;width:auto;vertical-align:middle" title="✅" alt="✅" /></li>
<li><strong>Safari</strong>: 26.2+ <img src="https://forum.exlends.ru/assets/plugins/nodebb-plugin-emoji/emoji/android/2705.png?v=a1e94250dac" class="not-responsive emoji emoji-android emoji--white_check_mark" style="height:23px;width:auto;vertical-align:middle" title="✅" alt="✅" /></li>
<li><strong>Edge</strong>: Пока <img src="https://forum.exlends.ru/assets/plugins/nodebb-plugin-emoji/emoji/android/274c.png?v=a1e94250dac" class="not-responsive emoji emoji-android emoji--x" style="height:23px;width:auto;vertical-align:middle" title="❌" alt="❌" />, ждем обновлений</li>
</ul>
<p dir="auto"><em>Важно</em>: В WeakMap методы работают аналогично, но ключи - только объекты.</p>
<h2>Практика: примеры в коде</h2>
<p dir="auto">Давайте разберем реальные кейсы. Первый - кэш пользовательских предпочтений: const prefs = new Map(); prefs.getOrInsert(‘theme’, ‘light’); Теперь prefs.get(‘theme’) всегда вернет строку.</p>
<p dir="auto">Второй - счетчики событий: const counters = new Map(); function increment(key) { counters.getOrInsertComputed(key, () =&gt; 0)++; } Атомарно увеличивает счетчик.</p>
<p dir="auto">Третий - группировка данных: const groups = new Map(); groups.getOrInsert(key, []).push(item); Массив всегда существует.</p>
<pre><code class="language-javascript">const cache = new Map();

// Настройки
function getOrSetTheme(key) {
  return cache.getOrInsert(key, 'light');
}

// Статистика
function countEvent(event) {
  const count = cache.getOrInsertComputed(event, () =&gt; 0);
  cache.set(event, count + 1);
  return count + 1;
}
</code></pre>
<h2>Новые возможности на горизонте</h2>
<p dir="auto">Методы getOrInsert открывают дверь для более эффективного кода в Chrome 145. Осталось внедрить их в библиотеки вроде Shaka Player, где уже обсуждают миграцию. Подумайте о WeakMap для временных данных - там утечки памяти под контролем.</p>
<p dir="auto">Дальше ждем полной кросс-браузерной поддержки и интеграции в фреймворки. Это шаг к JavaScript без boilerplate для коллекций.</p>
]]></description><link>https://forum.exlends.ru/topic/1429/chrome-145-map.getorinsert-dlya-atomarnyh-operacij-v-kollekciyah</link><generator>RSS for Node</generator><lastBuildDate>Sat, 17 Oct 2026 03:53:33 GMT</lastBuildDate><atom:link href="https://forum.exlends.ru/topic/1429.rss" rel="self" type="application/rss+xml"/><pubDate>Sun, 08 Mar 2026 17:51:57 GMT</pubDate><ttl>60</ttl></channel></rss>