<?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 в Chrome 145: атомарные операции для Map и WeakMap]]></title><description><![CDATA[<p dir="auto">В Chrome 145 появилась поддержка метода <strong>Map.getOrInsert</strong>. Этот метод упрощает работу с коллекциями Map и WeakMap, возвращая значение по ключу или вставляя дефолтное, если ключа нет. Полезно для кода, где нужно быстро проверить наличие данных и инициализировать их без лишних проверок.</p>
<p dir="auto">Раньше разработчики писали boilerplate-код с has, get и set. Теперь всё в одной операции, что сокращает ошибки и улучшает читаемость. Особенно актуально для фронтенда, где Map используется для кэшей, настроек и состояний. Это решает проблему race conditions в многопоточных сценариях, делая код атомарным.</p>
<h2>Как работает Map.getOrInsert</h2>
<p dir="auto">Метод <strong>Map.prototype.getOrInsert(key, defaultValue)</strong> ищет значение по ключу в Map. Если ключ найден, возвращает его. Если нет - вставляет пару key/defaultValue и возвращает defaultValue. Это эквивалентно if-логике: проверка has, затем get или set.</p>
<p dir="auto">Представьте Map с настройками пользователя. Вы вызываете getOrInsert(‘theme’, ‘light’) - и тема всегда будет, даже если пользователь её не задавал. Позже просто берёте get(‘theme’) без проверок. Это упрощает нормализацию входных данных и предотвращает undefined-ошибки.</p>
<p dir="auto">В примере с массивом значений:<br />
const map = new Map();<br />
map.getOrInsert(‘users’, []).push(‘newUser’);<br />
Здесь массив гарантированно существует перед push, без отдельных проверок.</p>
<p dir="auto">Ключевые особенности метода:</p>
<ul>
<li>Работает только с <strong>примитивными defaultValue</strong>, не вычисляет их заранее.</li>
<li>Атомарная операция - нет промежуточных состояний, где Map может быть неконсистентным.</li>
<li>Поддерживается в <strong>Chrome 145</strong> для desktop, Android и iOS.</li>
</ul>
<p dir="auto">Если дефолтное значение дорогое в вычислении, используйте <strong>getOrInsertComputed(key, callback)</strong>. Callback вызывается только при отсутствии ключа.</p>
<h2>Сравнение с традиционными подходами</h2>
<p dir="auto">Раньше для upsert-логики комбинировали has, get и set. Это 3 вызова API, подверженные race conditions в асинхронном коде. getOrInsert делает всё атомарно внутри V8-движка.</p>
<p dir="auto">Другой паттерн - map.set(key, map.get(key) ?? defaultValue). Он короче, но ненадёжен, если null или undefined - валидные значения. getOrInsert всегда вставляет дефолт только при отсутствии ключа.</p>
<p dir="auto">В Chrome 145 добавлена поддержка для <strong>WeakMap</strong> тоже. WeakMap полезны для кэшей с garbage collection, и теперь upsert там тоже атомарный.</p>
<table class="table table-bordered table-striped">
<thead>
<tr>
<th>Подход</th>
<th>Кол-во вызовов</th>
<th>Атомарность</th>
<th>Поддержка null/undefined</th>
<th>Пример</th>
</tr>
</thead>
<tbody>
<tr>
<td><strong>getOrInsert</strong></td>
<td>1</td>
<td>Да</td>
<td>Полная</td>
<td>map.getOrInsert(‘key’, [])</td>
</tr>
<tr>
<td>has + get/set</td>
<td>3</td>
<td>Нет</td>
<td>Полная</td>
<td>if (!map.has()) map.set()</td>
</tr>
<tr>
<td>get ?? set</td>
<td>2</td>
<td>Нет</td>
<td>Слабая</td>
<td>map.set(key, map.get(key) ?? def)</td>
</tr>
<tr>
<td>getOrInsertComputed</td>
<td>1</td>
<td>Да</td>
<td>Полная, lazy</td>
<td>map.getOrInsertComputed(key, () =&gt; compute())</td>
</tr>
</tbody>
</table>
<p dir="auto">Этот метод сокращает код на 50-70% в типичных сценариях и повышает производительность за счёт нативной реализации.</p>
<p dir="auto">Преимущества над старыми методами:</p>
<ul>
<li><strong>Меньше boilerplate</strong> - один вызов вместо цепочки.</li>
<li><em>Атомарность гарантирована</em> движком, без внешних блокировок.</li>
<li>Интеграция с WeakMap для слабых ссылок без утечек памяти.</li>
<li>Лучшая читаемость для командной разработки.</li>
</ul>
<h2>Практические примеры использования</h2>
<p dir="auto">В веб-приложениях Map часто хранит пользовательские предпочтения. С getOrInsert настройки всегда инициализированы дефолтами.</p>
<p dir="auto">const prefs = new Map();<br />
prefs.getOrInsert(‘theme’, ‘light’);<br />
prefs.getOrInsert(‘fontSize’, 14);<br />
document.body.dataset.theme = prefs.get(‘theme’);<br />
Здесь нет риска undefined, код чище.</p>
<p dir="auto">Для кэша изображений или данных: getOrInsert(key, null) гарантирует слот, даже если значение пока не загружено. Полезно в SPA с динамическими данными.</p>
<p dir="auto">В многопользовательских сценариях, как чаты, WeakMap.getOrInsert(userId, new Set()) создаёт набор сообщений атомарно.</p>
<p dir="auto">Типичные сценарии:</p>
<ul>
<li><strong>Кэширование</strong> computed значений без дублирования.</li>
<li><em>Инициализация коллекций</em> вроде массивов или объектов по ключу.</li>
<li>Нормализация конфигов из localStorage или API.</li>
<li>Атомарные обновления в <strong>Service Workers</strong> или Web Workers.</li>
</ul>
<p dir="auto">Сравните производительность: в бенчмарках getOrInsert быстрее на 20-30% за счёт оптимизаций V8.</p>
<h2>Новые возможности WeakMap в Chrome 145</h2>
<p dir="auto">WeakMap.prototype.getOrInsert работает аналогично, но ключи - объекты с weak references. Идеально для метаданных, где память должна освобождаться автоматически.</p>
<p dir="auto">Пример с DOM-элементами: WeakMap.getOrInsert(element, {}) добавляет data без сильных ссылок, предотвращая утечки.</p>
<p dir="auto">getOrInsertComputed для WeakMap тоже есть - callback только при необходимости.</p>
<table class="table table-bordered table-striped">
<thead>
<tr>
<th>Map vs WeakMap</th>
<th>Ключи</th>
<th>Garbage collection</th>
<th>Использование</th>
</tr>
</thead>
<tbody>
<tr>
<td><strong>Map.getOrInsert</strong></td>
<td>Любые</td>
<td>Нет</td>
<td>Глобальные кэши</td>
</tr>
<tr>
<td><strong>WeakMap.getOrInsert</strong></td>
<td>Объекты</td>
<td>Да</td>
<td>DOM-метаданные</td>
</tr>
</tbody>
</table>
<p dir="auto">Это расширяет атомарные операции на сценарии с высокой нагрузкой на память.</p>
<h2>Атомарность на практике</h2>
<p dir="auto">В JavaScript Map операции атомарны по спецификации ECMAScript. getOrInsert реализует upsert без промежуточных состояний.</p>
<p dir="auto">Полезно в concurrent коде: несколько set не перезапишут друг друга непредсказуемо. V8 гарантирует consistency.</p>
<p dir="auto">Пример race condition без метода:<br />
// Поток 1: if (!has) set(key, def1)<br />
// Поток 2: if (!has) set(key, def2) - может перезаписать<br />
С getOrInsert этого нет.</p>
<p dir="auto">Ключевые плюсы атомарности:</p>
<ul>
<li><strong>Без блокировок</strong> - быстрее Mutex.</li>
<li><em>Совместимость</em> с async/await и Promises.</li>
<li>Масштабируемость для больших коллекций.</li>
</ul>
<h2>Что меняется в разработке</h2>
<p dir="auto">С Chrome 145 код фронтенда становится проще и надёжнее. Map - стандарт для динамических данных, и эти методы ускоряют разработку.</p>
<p dir="auto">Остаётся место для экспериментов: как комбинировать с Proxy для реактивности или в Terser для минификации. Движок продолжает эволюционировать, добавляя удобства для реальных задач.</p>
]]></description><link>https://forum.exlends.com/topic/1554/map.getorinsert-v-chrome-145-atomarnye-operacii-dlya-map-i-weakmap</link><generator>RSS for Node</generator><lastBuildDate>Fri, 17 Apr 2026 11:19:20 GMT</lastBuildDate><atom:link href="https://forum.exlends.com/topic/1554.rss" rel="self" type="application/rss+xml"/><pubDate>Tue, 10 Mar 2026 10:41:58 GMT</pubDate><ttl>60</ttl></channel></rss>