Пошук уроків, статей та іншого контенту
Навчіться використовувати ?? для встановлення значень за замовчуванням лише у випадку null або undefined. З'ясуйте важливу різницю між ?? та логічним оператором ||.
??Оператор nullish coalescing ?? повертає значення праворуч лише тоді, коли значення ліворуч дорівнює null або undefined.
const username = null ?? "Гість";
console.log(username); // "Гість"Якщо ліве значення не є null або undefined, повертається саме воно:
console.log("Іван" ?? "Гість"); // "Іван"
console.log(0 ?? 100); // 0
console.log(false ?? true); // false
console.log("" ?? "Текст"); // ""Це дає змогу встановлювати значення за замовчуванням, не замінюючи інші допустимі, але «хибні» значення.
?? та ||Оператор || повертає праве значення, якщо ліве є falsy-значенням.
До таких значень належать:
false;
0;
-0;
0n;
"";
null;
undefined;
NaN.
Оператор ?? перевіряє лише null і undefined.
const timeout = 0;
console.log(timeout || 5000); // 5000
console.log(timeout ?? 5000); // 0У цьому прикладі 0 може бути коректним значенням тайм-ауту. Оператор || помилково замінює його, а ?? зберігає.
Ще один приклад:
const settings = {
showHints: false,
fontSize: 0,
nickname: ""
};
console.log(settings.showHints || true); // true
console.log(settings.showHints ?? true); // false
console.log(settings.fontSize || 16); // 16
console.log(settings.fontSize ?? 16); // 0
console.log(settings.nickname || "Користувач"); // "Користувач"
console.log(settings.nickname ?? "Користувач"); // ""Вибір оператора залежить від вимог:
використовуйте ??, якщо значення за замовчуванням потрібне тільки для null або undefined;
використовуйте ||, якщо будь-яке falsy-значення має вважатися відсутнім або непридатним.
Оператор можна використовувати в ланцюжку:
const value = null ?? undefined ?? "Значення" ?? "Інше значення";
console.log(value); // "Значення"Вирази перевіряються зліва направо. Повертається перше значення, яке не є null або undefined.
Якщо всі значення є null або undefined, результатом буде останнє значення:
const value = null ?? undefined;
console.log(value); // undefinedОператор ?? також можна використовувати для обчислення значення праворуч:
function getPort(config) {
return config.port ?? 3000;
}
console.log(getPort({ port: 8080 })); // 8080
console.log(getPort({ port: null })); // 3000
console.log(getPort({})); // 3000Правий операнд обчислюється лише тоді, коли лівий операнд має значення null або undefined:
function createDefaultSettings() {
console.log("Створення налаштувань за замовчуванням");
return {
theme: "light"
};
}
const savedSettings = {
theme: "dark"
};
const settings = savedSettings ?? createDefaultSettings();
console.log(settings); // { theme: "dark" }У цьому прикладі createDefaultSettings() не викликається, оскільки savedSettings уже має значення.
Оператор ?? особливо корисний під час читання необов'язкових властивостей:
const user = {
name: "Олена",
age: 0,
bio: null
};
const name = user.name ?? "Невідомий користувач";
const age = user.age ?? 18;
const bio = user.bio ?? "Опис відсутній";
console.log(name); // "Олена"
console.log(age); // 0
console.log(bio); // "Опис відсутній"Властивість age має значення 0, тому воно не замінюється на 18. Властивість bio має значення null, тому використовується значення за замовчуванням.
Якщо сам об'єкт може бути null або undefined, зручно поєднати ?. та ??:
const response = {
data: {
profile: {
displayName: ""
}
}
};
const displayName = response?.data?.profile?.displayName ?? "Гість";
console.log(displayName); // ""Оператор optional chaining ?. безпечно перевіряє вкладені властивості, а ?? встановлює запасне значення лише за відсутності результату.
const emptyResponse = null;
const language = emptyResponse?.data?.language ?? "uk";
console.log(language); // "uk"?? корисний, коли функція приймає параметри, які можуть бути null або undefined:
function createUser(name, role) {
const actualName = name ?? "Гість";
const actualRole = role ?? "user";
return {
name: actualName,
role: actualRole
};
}
console.log(createUser("Марія", "admin"));
// { name: "Марія", role: "admin" }
console.log(createUser(null, undefined));
// { name: "Гість", role: "user" }
console.log(createUser("", "moderator"));
// { name: "", role: "moderator" }Порожній рядок у третьому виклику залишається без змін, оскільки "" не є null або undefined.
Для простих параметрів можна також використати значення за замовчуванням у декларації функції:
function greet(name = "Гість") {
return `Вітаємо, ${name}!`;
}
console.log(greet()); // "Вітаємо, Гість!"
console.log(greet(undefined)); // "Вітаємо, Гість!"
console.log(greet(null)); // "Вітаємо, null!"Важлива різниця: параметр зі значенням за замовчуванням замінює лише undefined, але не null. Якщо потрібно обробляти і null, використовуйте ??:
function greetUser(name) {
return `Вітаємо, ${name ?? "Гість"}!`;
}
console.log(greetUser(null)); // "Вітаємо, Гість!"??=JavaScript також має оператор nullish assignment ??=.
Він присвоює значення змінній або властивості лише тоді, коли поточне значення дорівнює null або undefined.
const options = {
retries: 0,
timeout: null
};
options.retries ??= 3;
options.timeout ??= 5000;
options.cache ??= true;
console.log(options);
// { retries: 0, timeout: 5000, cache: true }Значення retries: 0 не змінюється, оскільки 0 є допустимим значенням.
Приблизно такий код:
options.timeout ??= 5000;еквівалентний:
if (options.timeout === null || options.timeout === undefined) {
options.timeout = 5000;
}Оператор ?? має власний пріоритет. Під час поєднання з іншими операторами використовуйте дужки, щоб явно визначити порядок обчислення:
const value = (null ?? "текст") || "запасне значення";
console.log(value); // "текст"JavaScript забороняє безпосередньо змішувати ?? з || або && без дужок:
// Синтаксична помилка:
// const value = null || undefined ?? "значення";Правильний варіант:
const first = (null || undefined) ?? "значення";
const second = null ?? (undefined || "значення");
console.log(first); // "значення"
console.log(second); // "значення"Це обмеження допомагає уникати неоднозначних виразів.
Розглянемо функцію, яка готує налаштування застосунку:
function prepareConfig(input) {
const config = input ?? {};
return {
host: config.host ?? "localhost",
port: config.port ?? 3000,
debug: config.debug ?? false,
logLevel: config.logLevel ?? "info"
};
}
console.log(prepareConfig({
host: "example.com",
port: 0,
debug: false
}));
console.log(prepareConfig(null));Результат:
{
host: "example.com",
port: 0,
debug: false,
logLevel: "info"
}
{
host: "localhost",
port: 3000,
debug: false,
logLevel: "info"
}Значення 0 і false залишилися без змін, а відсутня властивість logLevel отримала значення за замовчуванням.
||, коли 0, false або "" є валіднимиconst page = 0;
const wrongPage = page || 1;
const correctPage = page ?? 1;
console.log(wrongPage); // 1
console.log(correctPage); // 0Якщо 0 є допустимим значенням, використовуйте ??.
?? замінює будь-яке «порожнє» значенняconst value = "" ?? "Значення";
console.log(value); // ""Порожній рядок не замінюється, тому що він не є null або undefined.
?? до змінної, яка не оголошена// ReferenceError:
// const result = missingVariable ?? "значення";Оператор ?? не захищає від звернення до змінної, якої взагалі не існує. Змінна має бути оголошена:
let value;
const result = value ?? "значення";
console.log(result); // "значення"null і undefinedОбидва значення запускають праву частину ??, але вони можуть мати різний зміст:
undefined часто означає, що значення не було задане;
null часто означає навмисну відсутність значення.
console.log(undefined ?? "запасне"); // "запасне"
console.log(null ?? "запасне"); // "запасне"У складнішій логіці за потреби перевіряйте ці значення окремо.
?? і || без дужок// Синтаксична помилка:
// const result = value ?? fallback || anotherFallback;Потрібно явно вказати порядок:
const result = (value ?? fallback) || anotherFallback;?? повертає праве значення лише для null або undefined.
Значення 0, false, "" і NaN не замінюються оператором ??.
|| вважає всі falsy-значення відсутніми, тому його поведінка відрізняється.
?? зручно використовувати для властивостей об'єктів, параметрів функцій і конфігурацій.
??= встановлює значення властивості лише тоді, коли вона null або undefined.
?? не можна безпосередньо змішувати з || або && без дужок.
Обирайте ??, коли потрібно відрізняти відсутнє значення від інших допустимих значень.