Оператор null-злиття (??)
Оператор null-злиття (??
) – логічний оператор, що повертає свій правий операнд, коли його лівий операнд – null
чи undefined
, інакше – повертає лівий оператор.
Спробуйте його в дії
Синтаксис
leftExpr ?? rightExpr
Опис
Оператор null-злиття може розглядатися як особливий випадок оператора логічного АБО (||
). Останній повертає правий операнд, якщо лівий операнд дорівнює будь-якому зі значень хибності, а не лише null
чи undefined
. Інакше кажучи, якщо застосувати ||
для надання певній змінній усталеного значення, то можна зіткнутися з неочікуваною поведінкою, якщо частина значень хибності усе ж є корисною (наприклад, ''
або 0
). Нижче є більше прикладів.
Оператор null-злиття має п'ятий з кінця пріоритет оператора – зразу після ||
і зразу перед умовним (тернарним) оператором.
Як оператор логічного І (&&
), так і оператор логічного АБО (||
) не можна безпосередньо поєднувати з ??
. Така спроба призведе до викидання синтаксичної помилки.
null || undefined ?? "foo"; // запускає SyntaxError
true && undefined ?? "foo"; // запускає SyntaxError
Натомість слід додати дужки, для явного задання пріоритету:
(null || undefined) ?? "foo"; // повертає "foo"
Приклади
Застосування оператора null-злиття
В цьому прикладі надаються усталені значення, однак значення, відмінні від null
чи undefined
, зберігаються.
const nullValue = null;
const emptyText = ""; // хибність
const someNumber = 42;
const valA = nullValue ?? "усталене для A";
const valB = emptyText ?? "усталене для B";
const valC = someNumber ?? 0;
console.log(valA); // "усталене для A"
console.log(valB); // "" (оскільки порожній рядок не є null чи undefined)
console.log(valC); // 42
Присвоєння змінній усталеного значення
Раніше при потребі присвоїти змінній усталене значення загальноприйнятим патерном було використання логічного оператора АБО (||
):
let foo;
// foo ніколи не було присвоєне будь-яке значення, тож в ній досі undefined
const someDummyText = foo || "Привіт!";
Проте у зв'язку з тим, що ||
– булів логічний оператор, його лівий операнд зводиться до булевого значення, і будь-яке значення хибності (0
, ''
, NaN
, null
, false
тощо) не повертається. Така логіка може призвести до неочікуваних наслідків, якщо 0
, ''
чи NaN
вважаються дійсними значеннями.
const count = 0;
const text = "";
const qty = count || 42;
const message = text || "агов!";
console.log(qty); // 42, а не 0
console.log(message); // "агов!", а не ""
Оператор null-злиття уникає цієї пастки, повертаючи другий операнд, коли перший зводиться або до null
, або до undefined
(але не до інших значень хибності):
const myText = ""; // Порожній рядок (що також є значенням хибності)
const notFalsyText = myText || "Привіт, світе";
console.log(notFalsyText); // Привіт, світе
const preservingFalsy = myText ?? "Привіт, сусіди";
console.log(preservingFalsy); // '' (оскільки myText не є ані undefined, ані null)
Закорочення
Подібно до логічних операторів АБО та І, вираз справа не обчислюється, якщо вираз зліва не є ані null
, ані undefined
.
function a() {
console.log("a була викликана");
return undefined;
}
function b() {
console.log("b була викликана");
return false;
}
function c() {
console.log("c була викликана");
return "foo";
}
console.log(a() ?? c());
// Виводить "a була викликана", потім "c була викликана", і потім – "foo"
// оскільки a() повертає undefined, тож обчислюються обидва вирази
console.log(b() ?? c());
// Виводить "b була викликана", потім "false"
// оскільки b() повернув false (а не null чи undefined), то вираз
// справа не був обчислений
Взаємини з оператором необов'язкового ланцюжка (?.)
Оператор null-злиття обробляє undefined
і null
як особливі значення, так само як оператор необов'язкового ланцюжка (?.
), котрий є корисним для доступу до властивості об'єкта, котрий може виявитись null
чи undefined
. Поєднуючи їх, можна безпечно звертатися до властивості об'єкта, котрий може виявитись відсутнім, і задати усталене значення на такий випадок.
const foo = { someFooProp: "привіт" };
console.log(foo.someFooProp?.toUpperCase() ?? "недоступно"); // "ПРИВІТ"
console.log(foo.someBarProp?.toUpperCase() ?? "недоступно"); // "недоступно"
Специфікації
Сумісність із браузерами
desktop | mobile | server | ||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
Nullish coalescing operator ( ?? )
|
Chrome Full support 80 | Edge Full support 80 | Firefox Full support 72 | Internet Explorer No support Ні | Opera Full support 67 | Safari Full support 13.1 | WebView Android Full support 80 | Chrome Android Full support 80 | Firefox for Android Full support 79 | Opera Android Full support 57 | Safari on iOS Full support 13.4 | Samsung Internet Full support 13.0 | Deno Full support 1.0 | Node.js Full support 14.0.0 |