Оператор об’єднання з null записується як два знаки питання ??.
Оскільки null і undefined сприймаються однаково, ми введемо спеціальну домовленість. В цій статті ми будемо вважати, що значення виразу “визначене”, якщо воно відрізняється від null та undefined.
Результатом a ?? b буде:
a, якщоaвизначене,b, якщоaне визначене.
Інакше кажучи, ?? повертає перший аргумент, якщо він не null/undefined. Інакше, другий.
Оператор об’єднання з null не є абсолютно новим. Це просто хороший синтаксис, щоб отримати перше “визначене” значення з двох.
Ми можемо переписати вираз result = a ?? b, використовуючи оператори, які ми вже знаємо:
result = (a !== null && a !== undefined) ? a : b;
Тепер повинно бути абсолютно зрозуміло, що робить ??. Подивімось, де це допомагає.
Наприклад, тут ми показуємо значення у змінній user, якщо її значення не null/undefined, інакше – показуємо Анонімний:
Ось приклад з user, якому не присвоєне ім’я:
let user;
alert(user ?? "Анонімний"); // Анонімний (user є undefined)
Ми також можемо використовувати послідовність з ??, щоб вибрати перше значення зі списку, яке не є null/undefined.
Скажімо, у нас є дані користувача в змінних firstName, lastName або nickName. Всі вони можуть бути не визначені, якщо користувач вирішив не вводити значення.
Ми хотіли б показати ім’я користувача, використовуючи одну з цих змінних, або показати “Анонімний”, якщо всі вони null/undefined.
Використаймо оператор ?? для цього:
let firstName = null;
let lastName = null;
let nickName = "Суперкодер";
// показує перше визначене значення:
alert(firstName ?? lastName ?? nickName ?? "Анонімний"); // Суперкодер
Порівняння з ||
Оператор АБО || може бути використаний таким же чином, як ??, як це було описано в попередній главі.
Наприклад, у коді вище, ми могли б замінити ?? на || і все ще отримали б той самий результат:
let firstName = null;
let lastName = null;
let nickName = "Суперкодер";
// показує перше істинне значення:
alert(firstName || lastName || nickName || "Анонімний"); // Суперкодер
Історично, оператор АБО || був першим. Він існує з початку JavaScript, тому розробники використовували його для цих цілей протягом тривалого часу.
З іншого боку, оператор об’єднання з null ?? було нещодавно додано в JavaScript, і причиною того було те, що люди були не дуже задоволені ||.
Важлива різниця між ними полягає в тому, що:
||повертає перше істинне значення.??повертає перше визначене значення.
Інакше кажучи, оператор || не розрізняє, чи значення false, 0, порожній рядок "" чи null/undefined. Всі вони однакові – хибні значення. Якщо будь-яке з них є першим аргументом ||, тоді ми отримаємо другий аргумент як результат.
Однак на практиці, ми хочемо використовувати типове значення лише тоді, коли змінна null/undefined. Тобто, коли значення дійсно невідоме/не встановлене.
Наприклад, розгляньте це:
let height = 0;
alert(height || 100); // 100
alert(height ?? 100); // 0
height || 100перевіряє чи має зміннаheightмає хибне значення, і0– це дійсно хибне значення.- отже, результатом
||є другий аргумент,100.
- отже, результатом
height ?? 100перевіряє зміннуheight, чи вонаnull/undefined, і це не так,- отже, результат –
height“як є”, тобто0.
- отже, результат –
На практиці нульова висота часто є дійсним значенням, яке не слід замінювати на типове значення. Отже, ?? робить саме те, що треба.
Пріоритет
Пріоритет оператора ?? такий самий, як у ||. Він дорівнює 3 у таблиці MDN.
Це означає, що, як і ||, оператор об’єднання з null ?? оцінюється до = та ?, але після більшості інших операцій, таких як +, *.
let height = null;
let width = null;
// важливо: використовуйте дужки
let area = (height ?? 100) * (width ?? 50);
alert(area); // 5000
В іншому випадку, якщо ми опускаємо дужки, то, оскільки * має вищий пріоритет, ніж ??, то він буде виконуватися першим, що призводить до неправильних результатів.
// без дужок
let area = height ?? 100 * width ?? 50;
// ...працює так само, як попередній вираз (мабуть, це не те, що ми хочемо):
let area = height ?? (100 * width) ?? 50;
Використання ?? разом з && або ||
З міркувань безпеки, JavaScript забороняє використання ?? разом з операторами && та ||, якщо пріоритет явно не вказаний дужками.
Код нижче викликає синтаксичну помилку:
let x = 1 && 2 ?? 3; // Синтаксична помилка
Обмеження є досить спірним, воно було додано до специфікації мови з метою уникнення помилок програмування, коли люди почнуть переходити з || до ??.
Використовуйте явні дужки, щоб працювати з цим оператором:
let x = (1 && 2) ?? 3; // Працює
alert(x); // 2
Підсумки
-
Оператор об’єднання з null
??надає короткий спосіб вибору першого “визначеного” значення зі списку.Він використовується для присвоєння типових значень до змінних:
// встановлює height=100, якщо height null чи undefined height = height ?? 100; -
Оператор
??має дуже низький пріоритет – трохи вищий, ніж?та=, тому розглядайте додавання дужок при використанні його у виразах. -
Цей оператор заборонено використовувати з
||або&&без явних дужок.
Коментарі
<code>, для кількох рядків – обгорніть їх тегом<pre>, для понад 10 рядків – використовуйте пісочницю (plnkr, jsbin, codepen…)