Оператор nullish coalescing (??)
Оператор ?? (nullish coalescing, об'єднання з null) повертає лівий операнд, якщо той не є null і не є undefined, а інакше повертає правий. Це спосіб задати значення за замовчуванням саме для «відсутнього» значення, а не для будь-якого falsy.
Теорія
TL;DR
a ?? b: якщоaнеnullі неundefined, повертаєтьсяa, інакшеb.||спрацьовує на всіх falsy значеннях,??тільки на nullish (null,undefined).- Тому
0 ?? 100дає0, а0 || 100дає100. - Правий операнд обчислюється лише за потреби, це теж коротке замикання.
??не можна змішувати з&&чи||без дужок, будеSyntaxError.
Швидкий приклад
const name = null;
const displayName = name ?? 'Guest';
console.log(displayName); // "Guest"
null ?? 'default' // "default"
undefined ?? 'default' // "default"
0 ?? 100 // 0
'' ?? 'текст' // ""
false ?? true // falseСинтаксис і як читати вираз
a ?? bЧитається так: «якщо a не null і не undefined, повернути a, інакше повернути b».
Формально це еквівалент такого запису:
value1 ?? value2
// якщо value1 !== null && value1 !== undefined -> повернути value1
// інакше -> повернути value2Як і || та &&, оператор ?? працює з коротким замиканням: правий операнд не обчислюється, коли лівий уже придатний.
Порівняння з || (логічним АБО)
Оператори схожі, але різниця принципова: || вважає «порожніми» усі falsy значення (0, '', false, NaN, null, undefined), а ?? реагує лише на null і undefined.
const a = 0;
console.log(a || 100); // 100, бо 0 є falsy
console.log(a ?? 100); // 0, бо 0 не є nullishТобто ?? зберігає такі значення, як 0, false та ''.
Значення a | a || 'default' | a ?? 'default' |
|---|---|---|
undefined | 'default' | 'default' |
null | 'default' | 'default' |
0 | 'default' | 0 |
false | 'default' | false |
'' | 'default' | '' |
'text' | 'text' | 'text' |
Практичні приклади
Значення з об'єкта конфігурації, де false є валідним вибором користувача:
const settings = {
theme: null,
notifications: false,
};
const theme = settings.theme ?? 'light';
const notifications = settings.notifications ?? true;
console.log(theme); // "light"
console.log(notifications); // false, значення не підмінилосяnotifications не стало true, бо false не є ні null, ні undefined.
Значення за замовчуванням для аргумента функції, який може бути пропущений або явно null:
function greet(name) {
const user = name ?? 'Guest';
console.log(`Hello, ${user}!`);
}
greet('Maria'); // "Hello, Maria!"
greet(null); // "Hello, Guest!"
greet(); // "Hello, Guest!"Типові місця застосування:
const page = config.page ?? 1; // значення за замовчуванням
const userName = response.data.name ?? 'Anonymous'; // дані з API
console.log(`Hello, ${user.name ?? 'guest'}!`); // відображення в інтерфейсіПріоритет і обов'язкові дужки
?? не можна змішувати з && або || в одному виразі без дужок: мова навмисно забороняє це, щоб ніхто не вгадував пріоритет.
const result = (a ?? b) && c; // правильноБез дужок код не скомпілюється:
SyntaxError: Unexpected token '&&'Часто ?? поєднують з optional chaining, і тоді дужки не потрібні, бо ?. не є логічним оператором:
const city = user?.address?.city ?? 'Unknown';Підсумкова таблиця
| Характеристика | Оператор ?? | Оператор || |
|---|---|---|
| Перевіряє | лише null і undefined | усі falsy (0, '', false, NaN, null, undefined) |
| Повертає | перше не-nullish значення | перше truthy значення |
| Застосовують для | значень за замовчуванням | логічних перевірок |
Типові помилки
- Використовують
||для числових значень за замовчуванням.count || 10перетворить коректний0на10. Для таких випадків потрібен??. - Змішують
??з&&чи||без дужок. Це не попередження лінтера, а справжнійSyntaxErrorна етапі парсингу. - Очікують, що
??відсіє порожній рядок.'' ?? 'default'повертає''. Якщо порожній рядок теж треба замінити, перевіряйте його явно:value?.trim() || 'default'. - Плутають
??з?..?.безпечно читає властивість і даєundefined, а??підставляє значення. Вони доповнюють одне одного, а не замінюють. - Думають, що
??=те саме, що=. Оператор присвоєнняx ??= 5записує значення лише тоді, колиxєnullабоundefined.
Коротка відповідь
Для співбесідиКоротка відповідь допоможе вам впевнено відповідати на цю тему під час співбесіди.