Оператор null-об'єднання (??
) - це логічний оператор, який повертає свій правий операнд, якщо його лівий операнд дорівнює null
чи undefined
, інакше, він повертає свій лівий операнд.
На відміну від логічного АБО (||
), лівий операнд повертається, якщо це хибне значення, яке не дорівнює null
чи undefined
. Іншими словами, якщо ви використовуєте ||
для надання значення за замовчуванням іншій змінній foo
, ви можете зіткнутися з неочікуваною поведінкою, якщо використовуєте хибні значення (напр., ''
або 0
). Дивіться нижче більше прикладів.
The source for this interactive example is stored in a GitHub repository. If you'd like to contribute to the interactive examples project, please clone https://github.com/mdn/interactive-examples and send us a pull request.
See PR #1482 regarding the addition of this example.
Синтаксис
лівийВираз ?? правийВираз
Опис
Оператор null-об'єднання повертає результати свого правого виразу, якщо лівий вираз дорівнює або null
, або undefined
.
Присвоєння змінній значення за замовчуванням
Раніше, якщо потрібно було присвоїти змінній значення за замовчуванням, звичайною практикою було використання логічного оператора АБО (||
):
let foo; ... // змінній foo ще не присвоювали значення, тому вона ще дорівнює undefined let someDummyText = foo || 'Привіт!';
Однак, через те, що ||
є булевим логічним оператором, лівий операнд примусово приводився до булевого значення для обчислення, і будь-яке хибне значення (0
, ''
, NaN
, null
, undefined
) не поверталось. Ця поведінка може спричинити несподівані наслідки, якщо ви розглядаєте 0
, ''
чи NaN
як коректні значення.
let count; let text; ... count = 0; text = ""; ... let qty = count || 42; let message = text || "привіт!"; console.log(qty); // 42, а не 0 console.log(message); // "привіт!", а не ""
Оператор null-об'єднання уникає цієї пастки, повертаючи другий операнд лише тоді, коли перший повертає або null
, або undefined
(і ніяке інше хибне значення):
let myText = ''; // Порожній рядок (який також є хибним значенням) let notFalsyText = myText || 'Привіт'; console.log(notFalsyText); // Привіт let 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), правий // вираз не обчислювався
Не утворює ланцюгів з операторами І чи АБО
Неможливо об'єднати оператори І (&&
) та АБО (||
) безпосередньо з ??
. В таких випадках буде викинуто помилку SyntaxError
.
null || undefined ?? "foo"; // викидає SyntaxError true || undefined ?? "foo"; // викидає SyntaxError
Однак, використання дужок для явного зазначення пріоритетності, є коректним:
(null || undefined ) ?? "foo"; // вертає "foo"
Зв'язок з оператором необов'язкового ланцюгування (?.
)
Оператор null-об'єднання ставиться до значень undefined
та null
особливим чином, так само, як оператор необов'язкового ланцюгування (?.
), який є корисним для доступу до властивостей об'єкта, які можуть дорівнювати null
чи undefined
.
let foo = { someFooProp: "привіт" }; console.log(foo.someFooProp?.toUpperCase()); // "ПРИВІТ" console.log(foo.someBarProp?.toUpperCase()); // undefined
Приклади
У цьому прикладі ми задаємо початкові значення, але залишаємо значення, які не дорівнюють null
чи undefined
.
function getMiscObj(){ return { aNullProperty: null, emptyText: "", someNumber: 42 }; }; const miscObj = getMiscObj(); const newObj = {}; newObj.propA = miscObj.aNullProperty ?? "початкове для A"; newObj.propB = miscObj.emptyText ?? "початкове для B"; newObj.propC = miscObj.someNumber ?? 0; console.log(newObj.propA); // "початкове для A" console.log(newObj.propB); // "" (оскільки порожній рядок не дорівнює null чи undefined) console.log(newObj.propC); // 42
Специфікації
Специфікація | Статус | Коментар |
---|---|---|
Proposal for the "nullish coalescing" operator | Стадія 3 |
Сумісність з веб-переглядачами
Desktop | Mobile | Server | |||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|
Nullish coalescing operator (?? ) | Chrome No support No | Edge No support No | Firefox No support No | IE No support No | Opera No support No | Safari No support No | WebView Android No support No | Chrome Android No support No | Firefox Android No support No | Opera Android No support No | Safari iOS No support No | Samsung Internet Android No support No | nodejs No support No |
Legend
- No support
- No support
- Experimental. Expect behavior to change in the future.
- Experimental. Expect behavior to change in the future.
Заувага: Відповідний PR вже був злитий, і дані скоро мають з'явитись на сторінці.
Хід реалізації
Наведена нижче таблиця надає щоденний статус реалізації цієї функціональності, оскільки функціональність ще не досягла кросбраузерної стабільності. Дані генеруються запуском відповідних тестів функціональності у Test262, стандартному тестовому наборі JavaScript, на нічній збірці чи на останньому релізі рушія JavaScript кожного веб-переглядача.