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

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

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

    В ECMAScript 2026 появился метод Map.getOrInsert, который упрощает работу с коллекциями. Он возвращает значение по ключу или вставляет дефолтное, если ключа нет. Это решает проблему ручных проверок has/get/set, делая код короче и надежнее.

    Метод уже работает в Chrome 145, что удобно для фронтенда. Зачем это нужно? В реальных проектах часто группируют данные или инициализируют структуры - без лишнего boilerplate. Теперь один вызов заменяет три операции, снижая ошибки в многопоточных сценариях.

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

    Метод Map.prototype.getOrInsert(key, defaultValue) ищет ключ в Map. Если находит - возвращает значение. Если нет - вставляет пару key/defaultValue и возвращает defaultValue. Это атомарная операция по спецификации ECMAScript 2026.

    Логика простая: сравнивает ключи через SameValue, канонизирует их. Не создает лишних записей, работает быстро. В отличие от ручного if (map.has(key)) { return map.get(key); } map.set(key, defaultValue); - здесь все в одном вызове. Это особенно полезно при группировке данных или кэшировании.

    Пример: представь обработку логов, где по userId собираешь массив событий.

    • Базовый вызов:
    const map = new Map();
    const events = map.getOrInsert('user123', []);
    events.push('login');
    console.log(map.get('user123')); // ['login']
    
    • С дефолтным объектом:
    const cache = new Map();
    const config = cache.getOrInsert('app', { timeout: 5000 });
    config.maxRetries = 3;
    

    Вот сравнение подходов:

    Подход Код Плюсы Минусы
    Ручной if (!map.has(key)) map.set(key, []); Полный контроль 3 вызова, race conditions
    getOrInsert map.getOrInsert(key, []) Один вызов, атомарно Только простые дефолты
    ?? оператор map.set(key, map.get(key) ?? defaultValue) Коротко Не вставляет, если null/undefined валидны

    Важно: Метод не вызывает колбэк всегда - только проверяет наличие.

    getOrInsertComputed для сложных случаев

    Если дефолтное значение требует вычислений, используй Map.prototype.getOrInsertComputed(key, callback). Колбэк вызывается только если ключа нет. Это экономит ресурсы - никаких лишних операций.

    Спецификация: сначала ищет ключ, если не находит - выполняет callback(key), затем вставляет и возвращает. Проверяет Map заново после колбэка на случай изменений. Идеально для дорогих инициализаций, как создание объектов или запросов.

    Пример группировки данных из API:

    const grouped = new Map();
    for (let item of data) {
      const list = grouped.getOrInsertComputed(item.category, () => new Set());
      list.add(item.id);
    }
    

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

    • Вызов колбэка только при необходимости - оптимизация производительности.
    • Атомарность: даже если Map меняется в колбэке, логика устойчива.
    • Поддержка WeakMap - для временных объектов без утечек памяти.

    Сравнение с getOrInsert:

    Метод Когда колбэк Использование
    getOrInsert Никогда Простые константы: [] или {}
    getOrInsertComputed Если ключа нет Сложные: new Proxy(), fetch()

    Нюанс: callback получает key как аргумент, возвращает значение.

    Поддержка в Chrome 145 и других движках

    В Chrome 145 метод доступен полностью, включая WeakMap-варианты. Firefox с 144, Safari с 26.2 - браузеры 2026 года на борту. Это часть proposal-upsert от TC39, вошедшего в ECMAScript 2026.

    Проверить поддержку можно через CanIUse: Chrome 145+ - зеленый свет. Для полифиллов подойдет core-js, но в новых проектах не нужно. WeakMap.getOrInsert полезен для кэшей DOM-элементов - ключи удаляются с мусором.

    Ключевые фичи поддержки:

    • Chrome 145: Map и WeakMap методы стабильны.
    • Edge 144+: частично, полная с 145.
    • Polyfill: !map.has(key) ? map.set(key, callback ? callback(key) : defaultValue) : map.get(key).

    Совет: Тестируй в devtools - console.log(new Map().getOrInsert(‘test’, 42)) работает сразу.

    Атомарность и типичные сценарии

    Map.getOrInsert гарантирует атомарность в single-threaded JS, но в Workers или с SharedArrayBuffer - осторожно с race conditions. Подходит для реактивных apps, где состояние мутирует часто.

    Рассмотрим сценарии: группировка в reducers, кэш конфигов, счетчики по ключам. Заменяет паттерны вроде map.get(key) ?? (map.set(key, defaultValue), defaultValue). Код чище, меньше багов с null/undefined.

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

    • Группировка: map.getOrInsert(userId, []).push(event).
    • Кэш: cache.getOrInsert(url, () => fetch(url).then(r => r.json()));
    • Счетчики: stats.getOrInsert(action, 0)++;

    Ограничение: Не для mutable defaultValue вроде [] - мутации видны всем.

    Новые горизонты для коллекций

    Map.getOrInsert открывает двери для более declarative кода в JS. Остается внедрение в Node.js и полная кросс-браузерность. Стоит поэкспериментировать с WeakMap в garbage-collected структурах.

    Дальше - интеграция с Records/Tuples из будущих ECMA, где атомарность коллекций станет стандартом. Это шаг к более robust данным в веб-приложениях, без handmade оберток.

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

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

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

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

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

    Категории

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

    Контакты

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

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

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

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

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