Перейти к содержанию
  • Лента
  • Категории
  • Последние
  • Метки
  • Популярные
  • Пользователи
  • Группы
Свернуть
exlends
Категории
  1. Главная
  2. Категории
  3. Языки программирования
  4. JavaScript
  5. Map.getOrInsert в ECMAScript 2026: атомарные операции для Map

Map.getOrInsert в ECMAScript 2026: атомарные операции для Map

Запланировано Прикреплена Закрыта Перенесена JavaScript
map.getorinsertecmascript 2026javascript
1 Сообщения 1 Постеры 61 Просмотры
  • Сначала старые
  • Сначала новые
  • По количеству голосов
Ответить
  • Ответить, создав новую тему
Авторизуйтесь, чтобы ответить
Эта тема была удалена. Только пользователи с правом управления темами могут её видеть.
  • hannadevH Не в сети
    hannadevH Не в сети
    hannadev
    написал в отредактировано
    #1

    В ECMAScript 2026 появился метод Map.getOrInsert. Он возвращает значение по ключу или вставляет дефолтное, если ключа нет. Это упрощает работу с коллекциями и избавляет от boilerplate-кода с проверками has и set.

    Зачем это нужно? В реальных проектах часто приходится группировать данные или инициализировать структуры. Без getOrInsert приходится писать if-else, что увеличивает ошибки и усложняет код. Новый метод делает всё атомарно - одной строкой. Плюс есть версия getOrInsertComputed для ленивых вычислений.

    Как работает Map.getOrInsert

    Метод map.getOrInsert(key, defaultValue) ищет ключ в Map. Если находит - возвращает значение. Нет ключа - вставляет пару [key, defaultValue] и возвращает defaultValue. Всё происходит за один проход, без лишних вызовов has или get.

    Это эквивалентно коду:

    if (map.has(key)) {
      return map.get(key);
    }
    map.set(key, defaultValue);
    return defaultValue;
    

    Но короче и надёжнее, особенно если значения могут быть null или undefined. Пример: группировка данных по ключам. Проходим массив, для каждого ключа получаем массив или создаём новый - и пушим значения.

    Вот базовый синтаксис и поведение:

    • key: любой объект, сравнивается по ссылке.
    • defaultValue: вставляется только при отсутствии ключа.
    • Возвращает всегда значение по ключу после операции.
    Сценарий Код до Код с getOrInsert
    Простая инициализация if (!map.has(k)) map.set(k, []); map.get(k).push(v); map.getOrInsert(k, []).push(v);
    С объектом по умолчанию if (!map.has(k)) map.set(k, {}); map.getOrInsert(k, {});
    С null/undefined map.set(k, map.get(k) ?? def); map.getOrInsert(k, def);

    Отличия getOrInsert и getOrInsertComputed

    getOrInsert подходит, когда дефолт прост - число, строка, пустой массив. defaultValue вычисляется всегда при вызове, даже если ключ есть. Но если создание дефолта дорогое - объект с вычислениями или запрос - лучше getOrInsertComputed.

    Этот метод принимает колбэк: map.getOrInsertComputed(key, () => expensiveValue). Колбэк вызывается только если ключа нет. После вставки возвращает значение. Идеально для счётчиков или сложных структур, где не хочешь тратить ресурсы зря. В спецификации учтено, что Map может измениться во время колбэка - метод перепроверяет.

    Преимущества в списке:

    • Ленивое вычисление: колбэк не вызывается при наличии ключа.
    • Атомарность: вставка без гонок в однопотоке.
    • Поддержка в WeakMap для тех же сценариев.

    Пример подсчёта символов:

    const map = new Map();
    for (const char of "hello") {
      const counter = map.getOrInsertComputed(char, () => ({char, count: 0}));
      counter.count++;
    }
    

    Реальные примеры использования

    Представь группировку логов по пользователям. Для каждого ID пользователя нужен массив событий. Без getOrInsert: проверка has, get, push или set. С методом - чистая строка. Ещё кейс: кэш вычислений, где дефолт - результат функции.

    В многопоточных окружениях (Web Workers) атомарность помогает избежать дублей. Хотя JS однопоточный, в асинхронных сценариях это спасает от race conditions при параллельных вставках. Плюс WeakMap.getOrInsert для объектов без утечек памяти.

    Популярные паттерны:

    • Группировка: map.getOrInsert(key, []).push(value);
    • Счётчики: map.getOrInsert(key, 0) + 1;
    • Объекты: map.getOrInsertComputed(key, () => computeObject(key));
    Паттерн До ECMAScript 2026 С 2026
    Группировка массивов if (!m.has(k)) m.set(k,[]); m.get(k).push(v); m.getOrInsert(k,[]).push(v);
    Инициализация счётчика m.set(k, (m.get(k) 0) +1); m.getOrInsert(k,0) +1;
    Кэш с вычислением if(!m.has(k)) m.set(k, heavyFn(k)); m.getOrInsertComputed(k, () => heavyFn(k));

    Что меняется в проектах с ECMAScript 2026

    Теперь код чище, меньше ошибок от забытых проверок. Браузеры и Node.js поддержат это нативно - забудь полифилы из core-js. Для TypeScript типы уже готовы. Нюанс: ключи сравниваются SameValue, как в Map - по ссылке для объектов.

    Методы усиливают Map как основной инструмент для словарей. Раньше полагались на lodash или самописные хелперы. Теперь стандарт. Стоит обновить гайдлайны: предпочитай getOrInsert простым случаям, Computed - дорогим.

    Останутся вопросы по WeakMap-версиям или интеграции с Proxy. Там похожая логика, но для слабых ссылок - тема для разборов.

    1 ответ Последний ответ
    0

    Здравствуйте! Похоже, вас заинтересовала эта беседа, но у вас ещё нет аккаунта.

    Надоело каждый раз пролистывать одни и те же посты? Зарегистрировав аккаунт, вы всегда будете возвращаться на ту же страницу, где были раньше, и сможете выбирать, получать ли уведомления о новых ответах (по электронной почте или в виде push-уведомлений). Вы также сможете сохранять закладки и ставить лайки постам, чтобы выразить свою благодарность другим участникам сообщества.

    С вашими комментариями этот пост мог бы стать ещё лучше 💗

    Зарегистрироваться Войти

    Категории

    • Главная
    • Новости
    • Фронтенд
    • Бекенд
    • Языки программирования

    Контакты

    • Сотрудничество
    • info@exlends.com

    © 2024 - 2026 ExLends, Inc. Все права защищены.

    Политика конфиденциальности
    • Войти

    • Нет учётной записи? Зарегистрироваться

    • Войдите или зарегистрируйтесь для поиска.
    • Первое сообщение
      Последнее сообщение
    0
    • Лента
    • Категории
    • Последние
    • Метки
    • Популярные
    • Пользователи
    • Группы