Освойте оператор нулевого слияния (??) в JavaScript для чистого присвоения значений по умолчанию. Узнайте отличия от оператора ИЛИ (||) и рассмотрите примеры.
Оператор нулевого слияния (Nullish Coalescing) в JavaScript: Подробное руководство по присвоению значений по умолчанию
В JavaScript присвоение значений по умолчанию является обычной задачей. Традиционно разработчики использовали для этого оператор ИЛИ (||
). Однако оператор нулевого слияния (??
), введенный в ECMAScript 2020, предоставляет более точный и надежный способ обработки присвоений значений по умолчанию, особенно при работе со значениями null
или undefined
. Это руководство подробно описывает оператор нулевого слияния, исследуя его синтаксис, поведение, отличия от оператора ИЛИ и практические варианты использования.
Что такое нулевое слияние?
Оператор нулевого слияния (??
) — это логический оператор, который возвращает свой правый операнд, когда его левый операнд равен null
или undefined
. В противном случае он возвращает свой левый операнд. Проще говоря, он предоставляет значение по умолчанию только тогда, когда переменная строго равна null
или undefined
.
Синтаксис
Синтаксис оператора нулевого слияния прост:
leftOperand ?? rightOperand
Здесь leftOperand
— это переменная или выражение, которое вы хотите проверить на null
или undefined
, а rightOperand
— это значение по умолчанию, которое вы хотите присвоить, если leftOperand
действительно равно null
или undefined
.
Пример
Рассмотрим следующий пример:
const username = null ?? "Guest";
console.log(username); // Вывод: Guest
const age = undefined ?? 25;
console.log(age); // Вывод: 25
const city = "London" ?? "Unknown";
console.log(city); // Вывод: London
В этом примере username
присваивается значение по умолчанию "Guest", потому что оно изначально null
. Аналогично, age
присваивается 25, потому что оно начинается как undefined
. Однако city
сохраняет свое исходное значение, "London", потому что оно не является ни null
, ни undefined
.
Нулевые (Nullish) против ложных (Falsy) значений
Крайне важно понимать разницу между нулевыми (nullish) и ложными (falsy) значениями в JavaScript. Нулевое значение — это либо null
, либо undefined
. Ложное значение — это значение, которое считается ложным при встрече в булевом контексте. Ложные значения включают:
null
undefined
0
(ноль)NaN
(не число)''
(пустая строка)false
Ключевое отличие заключается в том, что оператор нулевого слияния проверяет только null
или undefined
, тогда как оператор ИЛИ (||
) проверяет любое ложное значение.
Разница между ??
и ||
Оператор ИЛИ (||
) — это логический оператор ИЛИ, который возвращает правый операнд, если левый операнд является ложным. Хотя его можно использовать для присвоения значений по умолчанию, он может привести к неожиданному поведению при работе со значениями, такими как 0
или пустая строка.
Пример: Недостатки ||
const quantity = 0 || 10; // Мы хотим, чтобы по умолчанию было 10, если quantity отсутствует
console.log(quantity); // Вывод: 10 (Неожиданно!) потому что 0 является ложным
const text = '' || 'Default Text'; //Мы хотим, чтобы по умолчанию был текст, если text отсутствует
console.log(text); // Вывод: Default Text (Неожиданно!) потому что '' является ложным
В первом примере мы предполагали присвоить значение по умолчанию 10 только в том случае, если quantity
отсутствовало (null
или undefined
). Однако, поскольку 0
является ложным значением, оператор ИЛИ некорректно присвоил значение по умолчанию. Аналогично, пустая строка приводит к тому, что отображается текст по умолчанию, даже если строка существует (но пуста).
Использование ??
для точности
Перепишем предыдущий пример, используя оператор нулевого слияния:
const quantity = 0 ?? 10;
console.log(quantity); // Вывод: 0 (Корректно!)
const text = '' ?? 'Default Text';
console.log(text); // Вывод: '' (Корректно!)
Теперь вывод соответствует ожиданиям. Оператор нулевого слияния проверяет только null
или undefined
, поэтому 0
и ''
рассматриваются как допустимые значения, и их исходные значения сохраняются.
Варианты использования нулевого слияния
Оператор нулевого слияния полезен в различных сценариях, где вам необходимо предоставить значения по умолчанию только тогда, когда переменная строго равна null
или undefined
. Вот несколько распространенных вариантов использования:
1. Обработка необязательных параметров функции
При определении функции с необязательными параметрами вы можете использовать оператор нулевого слияния для предоставления значений по умолчанию, если параметры не предоставлены.
function greet(name, greeting) {
const userName = name ?? "User";
const userGreeting = greeting ?? "Hello";
console.log(`${userGreeting}, ${userName}!`);
}
greet(); // Вывод: Hello, User!
greet("Alice"); // Вывод: Hello, Alice!
greet("Bob", "Greetings"); // Вывод: Greetings, Bob!
2. Установка параметров конфигурации по умолчанию
При работе с объектами конфигурации вы можете использовать оператор нулевого слияния, чтобы гарантировать использование значений по умолчанию, если некоторые параметры конфигурации не указаны.
const config = {
timeout: 5000,
retries: 3
};
function fetchData(options) {
const timeout = options.timeout ?? 10000; // Таймаут по умолчанию 10 секунд
const retries = options.retries ?? 5; // По умолчанию 5 повторных попыток
console.log(`Timeout: ${timeout}, Retries: ${retries}`);
}
fetchData(config); // Вывод: Timeout: 5000, Retries: 3
fetchData({}); // Вывод: Timeout: 10000, Retries: 5
fetchData({timeout:null, retries: undefined}); // Вывод: Timeout: 10000, Retries: 5
3. Доступ к вложенным свойствам объекта
При доступе к свойствам вложенных объектов оператор нулевого слияния может быть объединен с опциональной цепочкой (?.
) для предоставления значений по умолчанию, если какие-либо из промежуточных свойств равны null
или undefined
.
const user = {
profile: {
address: {
city: "New York"
}
}
};
const cityName = user?.profile?.address?.city ?? "Unknown";
console.log(cityName); // Вывод: New York
const unknownUser = {};
const unknownCityName = unknownUser?.profile?.address?.city ?? "Unknown";
console.log(unknownCityName); // Вывод: Unknown
4. Работа с API и внешними данными
При получении данных из API или внешних источников оператор нулевого слияния может использоваться для предоставления значений по умолчанию, если некоторые поля данных отсутствуют или имеют значения null
или undefined
. Рассмотрим получение данных пользователя из разных регионов. Предположим, что некоторые регионы могут не включать поле country
в данные пользователя.
async function getUserData(userId) {
try {
const response = await fetch(`https://api.example.com/users/${userId}`);
const data = await response.json();
const country = data.country ?? "Unknown Country";
const timezone = data.timezone ?? "UTC";
console.log(`User is from: ${country}, Timezone: ${timezone}`);
} catch (error) {
console.error("Error fetching user data:", error);
}
}
// Симуляция различных ответов API:
const userWithCountry = { name: "John", country: "USA", timezone: "EST" };
const userWithoutCountry = { name: "Jane", timezone: "GMT" };
// Для тестирования этого потребуется реальный API или имитация fetch.
// В демонстрационных целях, давайте сымитируем ответы:
global.fetch = async (url) => {
if (url.includes("123")) {
return { json: async () => userWithCountry };
} else if (url.includes("456")) {
return { json: async () => userWithoutCountry };
}
throw new Error("Unexpected URL");
};
getUserData(123); // Вывод: Пользователь из: USA, Часовой пояс: EST
getUserData(456); // Вывод: Пользователь из: Неизвестная страна, Часовой пояс: GMT
Приоритет операторов
Оператор нулевого слияния имеет относительно низкий приоритет. Он ниже, чем операторы ИЛИ (||
) и И (&&
). Поэтому при объединении оператора нулевого слияния с другими логическими операторами важно использовать скобки, чтобы явно определить порядок выполнения операций. Отсутствие скобок может привести к синтаксическим ошибкам или неожиданному поведению.
Пример: Использование скобок для ясности
// Без скобок (SyntaxError)
// const result = false || null ?? "Default"; // SyntaxError: Неожиданный токен '??'
// Со скобками (Корректно)
const result = false || (null ?? "Default");
console.log(result); // Вывод: Default
const anotherResult = (false || null) ?? "Default";
console.log(anotherResult); // Вывод: null
В первом примере отсутствие скобок приводит к SyntaxError
, потому что движок JavaScript не может определить предполагаемый порядок операций. Добавляя скобки, мы явно указываем движку сначала вычислить оператор нулевого слияния. Второй пример действителен; однако вывод отличается, потому что выражение ||
вычисляется первым.
Совместимость с браузерами
Оператор нулевого слияния (??
) является относительно новой функцией, поэтому крайне важно учитывать совместимость с браузерами, особенно если вы ориентируетесь на старые браузеры. Большинство современных браузеров поддерживают оператор нулевого слияния, включая:
- Chrome 80+
- Firefox 72+
- Safari 13.1+
- Edge 80+
- Node.js 14+
Если вам необходимо поддерживать старые браузеры, вы можете использовать транспилятор, такой как Babel, для преобразования вашего кода в совместимую версию JavaScript. Babel преобразует оператор ??
в эквивалентный код JavaScript, который работает в старых средах.
Лучшие практики
Вот несколько лучших практик для эффективного использования оператора нулевого слияния:
- Используйте
??
для проверок нулевых значений: Используйте оператор нулевого слияния (??
), когда вы специально хотите предоставить значение по умолчанию только тогда, когда переменная равнаnull
илиundefined
. - Используйте скобки для сложных выражений: При объединении оператора нулевого слияния с другими логическими операторами используйте скобки, чтобы четко определить порядок операций.
- Учитывайте совместимость с браузерами: Проверьте совместимость с браузерами и при необходимости используйте транспилятор для поддержки старых браузеров.
- Используйте последовательно: Применяйте
??
там, где это уместно, для более предсказуемого стиля кодирования во всем проекте. - Комбинируйте с опциональной цепочкой: Используйте
??
в сочетании с опциональной цепочкой?.
для безопасного доступа и присвоения значений по умолчанию вложенным свойствам объектов.
Глобальные аспекты
При разработке для глобальной аудитории учитывайте следующие моменты, связанные с присвоением значений по умолчанию:
- Локализация: Значения по умолчанию могут нуждаться в локализации в зависимости от языка или региона пользователя. Например, символ валюты по умолчанию или формат даты.
- Культурные нормы: Некоторые значения по умолчанию могут нуждаться в корректировке в зависимости от культурных норм. Например, сообщение приветствия по умолчанию может отличаться в разных культурах.
- Доступность: Убедитесь, что значения по умолчанию доступны и понятны пользователям с ограниченными возможностями. Предоставьте четкие и описательные метки для значений по умолчанию в пользовательских интерфейсах.
- Часовые пояса и даты: При работе с датами и временем используйте соответствующие часовые пояса и форматы даты, чтобы значения по умолчанию отображались корректно для пользователей в разных регионах.
Пример: Локализация с использованием нулевого слияния
Предположим, вы хотите отобразить сообщение приветствия по умолчанию на разных языках в зависимости от локали пользователя. Вы можете использовать оператор нулевого слияния, чтобы предоставить сообщение по умолчанию, если локализованное сообщение недоступно.
function getWelcomeMessage(locale) {
const localizedMessages = {
en: "Welcome!",
fr: "Bienvenue !",
de: "Willkommen!"
};
const message = localizedMessages[locale] ?? "Welcome!"; // По умолчанию английский, если локаль не найдена
return message;
}
console.log(getWelcomeMessage("fr")); // Вывод: Bienvenue !
console.log(getWelcomeMessage("es")); // Вывод: Welcome! (По умолчанию английский)
Заключение
Оператор нулевого слияния (??
) является ценным дополнением к языку JavaScript. Он предоставляет более точный и надежный способ присвоения значений по умолчанию по сравнению с оператором ИЛИ (||
), особенно при работе со значениями, такими как 0
или пустые строки. Понимая его синтаксис, поведение и варианты использования, вы можете писать более чистый и поддерживаемый код, который точно обрабатывает присвоения значений по умолчанию. Не забывайте учитывать совместимость с браузерами, приоритет операторов и глобальные аспекты при использовании оператора нулевого слияния в своих проектах.
Следуя лучшим практикам, изложенным в этом руководстве, вы сможете эффективно использовать оператор нулевого слияния для повышения качества и надежности вашего кода JavaScript, делая его более надежным и легким для понимания. Всегда помните о приоритете ясности и удобства сопровождения в вашем коде, и оператор нулевого слияния может стать мощным инструментом для достижения этих целей.