Nullish Coalescing ??
В одной фразе: ?? возвращает правый операнд только если левый — строго null или undefined, игнорируя остальные falsy-значения. Критически важен там где 0, "", false — валидные значения конфигурации, и || их “съедает”.
// Проблема: || заменяет все falsy — включая валидные значенияconst cfg = { timeout: 0, retries: 0, name: '' };
const timeout = cfg.timeout || 5000; // 5000 — ОШИБКА! 0 — валидный timeoutconst name = cfg.name || 'anon'; // 'anon' — ОШИБКА! '' — намеренно пусто
// ?? проверяет строго null/undefined:const timeout2 = cfg.timeout ?? 5000; // 0 — правильноconst name2 = cfg.name ?? 'anon'; // '' — правильно// ??= — nullish assignment (ES2021): присваивает только если null/undefinedlet user = { profile: null, settings: { theme: 'dark' } };
user.profile ??= { avatar: 'default.png' }; // присвоит (null)user.profile ??= { avatar: 'other.png' }; // не перезапишет (уже объект)
user.settings.theme ??= 'light'; // не перезапишет — 'dark' не nullishconsole.log(user.settings.theme); // 'dark'// Комбинирование ?? с ?. — паттерн безопасного доступаfunction getDisplayName(user) { return user?.name ?? 'Anonymous'; // user?. — если user null/undefined → undefined // ?? 'Anonymous' — если undefined → дефолт}
getDisplayName(null); // 'Anonymous'getDisplayName({ name: '' }); // '' — пустая строка не nullish!getDisplayName({ name: 'Bob' }); // 'Bob'Итог: ?? — точечный null-guard: срабатывает только на null/undefined. Идеален для параметров с дефолтами где 0 и "" осмысленны.