Skip to content

Latest commit

 

History

History
164 lines (106 loc) · 9.44 KB

File metadata and controls

164 lines (106 loc) · 9.44 KB

Оператор об’єднання з null '??'

[recent browser="new"]

Оператор об’єднання з null (англійською nullish coalescing operator) записується як два знаки питання ??.

Для зручності формулювання, далі в цій главі під виразом "визначене значення" ми будемо мати на увазі, що значення не є `null` і не є `undefined`.
Вираз "визначене значення" не є загальновизнаним терміном. Це придуманий нами вираз, який ми використовуємо в цій главі для зручності.

Вираз a ?? b поверне:

  • a, якщо a визначене,
  • b, якщо a не визначене.

Інакше кажучи, ?? повертає перший аргумент, якщо він не null/undefined. Або, якщо перший аргумент є 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 ??, і причиною цього було те, що люди були не до кінця задоволені ||.

Важлива різниця між ними полягає в тому, що:

  • || повертає перше істинне значення.
  • ?? повертає перше визначене значення.

Інакше кажучи, оператор || опрацьовує значення false, 0 і порожній рядок "" так само, як null/undefined. Бо вони всі є хибними значеннями (при перетворенні на булевий тип стають false). Оператор || поверне як результат другий аргумент не лише якщо значення є null/undefined. А і якщо значення є false, 0 чи порожнім рядком "".

Однак на практиці дуже часто ми хочемо використовувати типове значення (другий аргумент) лише тоді, коли значення змінної є саме null/undefined. Тобто, коли значення дійсно невідоме/не встановлене.

До прикладу:

let height = 0;

alert(height || 100); // 100
alert(height ?? 100); // 0
  • height || 100 перетворює значення змінної height в булеве значення, і тоді якщо воно false, то повертає другий аргумент. А 0 після перетворення в булеве значення теж буде false.
    • тут результатом || є другий аргумент, 100. Навіть тоді, коли значення 0 нас влаштовує.
  • 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;
  • Оператор ?? має дуже низький пріоритет -- трохи вищий, ніж ? та =, тому додавайте дужки при використанні його у виразах.

  • Цей оператор заборонено використовувати з || або && без явних дужок.