В чем разница между операторами && и ??
Комментарии (1)
Ответ сгенерирован нейросетью и может содержать ошибки
В чем разница между операторами && и ??
&& (логический И) и ?? (оператор нулевого слияния) — это два разных оператора в JavaScript, которые часто путают. Хотя оба используются для условной логики, они работают совершенно по-разному.
Оператор && (Логический И)
&& — это логический оператор, который вычисляет выражение слева направо и возвращает:
- ПЕРВОЕ falsy значение, если оно найдено
- ПОСЛЕДНЕЕ значение, если все значения truthy
console.log(true && 'hello'); // 'hello'
console.log(false && 'hello'); // false
console.log('hello' && 'world'); // 'world'
console.log('' && 'hello'); // '' (пустая строка — falsy)
console.log(null && 'hello'); // null
console.log(undefined && 'hello'); // undefined
console.log(0 && 'hello'); // 0 (ноль — falsy)
console.log(1 && 2 && 3); // 3
Falsy значения в JavaScript:
false0(и-0,0n)''(пустая строка)nullundefinedNaN
Оператор ?? (Nullish Coalescing)
?? — это оператор нулевого слияния, который возвращает:
- Правый операнд, если левый —
nullилиundefined - Левый операнд во всех остальных случаях
console.log(null ?? 'default'); // 'default'
console.log(undefined ?? 'default'); // 'default'
console.log('hello' ?? 'default'); // 'hello'
console.log(false ?? 'default'); // false (НЕ 'default'!)
console.log(0 ?? 'default'); // 0 (НЕ 'default'!)
console.log('' ?? 'default'); // '' (НЕ 'default'!)
console.log(false || 0 || '' ?? 'default'); // ''
Ключевое отличие
| Оператор | Проверяет | Возвращает |
|---|---|---|
&& | Истинность (truthy/falsy) | Первое falsy или последнее значение |
?? | Только null/undefined | Значение, если не null/undefined |
Практические примеры
Пример 1: Значения по умолчанию
const user = { name: 'John', email: null };
// Плохо с &&
const displayEmail1 = user.email && user.email; // null (falsy)
const displayEmail2 = user.email && 'email@example.com'; // null
// Хорошо с ??
const displayEmail = user.email ?? 'no-email@example.com'; // 'no-email@example.com'
Пример 2: Порядок проверки
const value = 0;
// && приравнивает 0 к falsy
const result1 = value && 'success'; // 0 (falsy)
// ?? учитывает только null/undefined
const result2 = value ?? 'default'; // 0 (valid value)
console.log(result1); // 0
console.log(result2); // 0
Пример 3: Пустые строки
const username = '';
// && считает пустую строку falsy
const display1 = username && 'Username'; // '' (falsy)
// ?? игнорирует пустую строку
const display2 = username ?? 'Anonymous'; // '' (valid value)
console.log(display1); // ''
console.log(display2); // ''
Использование в условиях
Пример 1: Условный рендер в React
// && часто используется для условного рендера
function Alert({ message }) {
return (
<div>
{message && <p className="error">{message}</p>} {/* Не рендерит, если message falsy */}
</div>
);
}
Alert({ message: '' }); // Ничего не рендерится
Alert({ message: 'Error' }); // Рендерит <p>Error</p>
Alert({ message: null }); // Ничего не рендерится
Это работает, потому что React не рендерит false, null, undefined.
Пример 2: Значения по умолчанию
// && — часто используется, но может быть опасен
const getConfig = (userConfig) => {
return userConfig && userConfig.settings || { default: true };
};
getConfig(null); // { default: true } — OK
getConfig({}); // { default: true } — OK
getConfig({ settings: {} }); // {} — OK
getConfig({ settings: false }); // { default: true } — НЕПРАВИЛЬНО!
// ?? — правильный подход
const getConfig = (userConfig) => {
return userConfig?.settings ?? { default: true };
};
getConfig({ settings: false }); // false — ПРАВИЛЬНО!
Цепочки операторов
Пример 1: && в цепочке
const user = {
profile: {
settings: {
notifications: true
}
}
};
// Проверка существования вложенных свойств
const hasNotifications = user && user.profile && user.profile.settings && user.profile.settings.notifications;
// Или с опциональной цепочкой (?.)
const hasNotifications = user?.profile?.settings?.notifications; // true
Пример 2: ?? в цепочке (более новое)
const config = {
apiUrl: null,
timeout: 0,
retries: undefined
};
// ?? для значений по умолчанию
const apiUrl = config.apiUrl ?? 'https://api.example.com';
const timeout = config.timeout ?? 5000; // ОШИБКА: 0 — valid value
const retries = config.retries ?? 3; // 3
console.log(apiUrl); // 'https://api.example.com'
console.log(timeout); // 0 (не 5000!)
console.log(retries); // 3
Комбинирование && и ??
// Комбинирование с опциональной цепочкой
const user = { email: null };
// && для проверки truthy
const sendEmail = user?.email && sendEmailToUser(user.email);
// ?? для значения по умолчанию
const display = user?.email ?? 'no-email@example.com';
// Вместе
const canNotify = user?.preferences?.notifications ?? true;
const willNotify = canNotify && sendNotification(user);
Когда использовать что
Используй &&:
- Для условного рендера в React
- Когда нужно проверить истинность значения
- Для логических цепочек
// Условный рендер
{isLoading && <Spinner />}
// Логическая цепочка
if (user && user.isAdmin && user.hasPermission('delete')) {
deleteItem();
}
Используй ??:
- Для значений по умолчанию
- Когда нужно различить
null/undefinedот других falsy значений - Когда ноль, пустая строка или false — valid значения
// Значение по умолчанию
const count = getUserCount() ?? 0;
const username = getUsername() ?? 'Anonymous';
const timeout = config.timeout ?? 5000;
Реальные примеры из проектов
API ответ с null значениями
const response = {
user: null,
articles: [],
meta: { total: 0 }
};
// Правильно с ??
const userName = response.user?.name ?? 'Guest';
const articleCount = response.articles?.length ?? 0;
const total = response.meta?.total ?? 'unknown';
Form валидация
const validateForm = (data) => {
const name = data.name && data.name.trim();
const email = data.email ?? '';
const age = data.age ?? 18;
return { name, email, age };
};
Конфигурация по умолчанию
const createConfig = (userConfig) => {
return {
apiUrl: userConfig?.apiUrl ?? 'https://api.example.com',
timeout: userConfig?.timeout ?? 5000,
debug: userConfig?.debug ?? false,
retries: userConfig?.retries ?? 3
};
};
const config = createConfig({ timeout: 0 }); // timeout будет 0, правильно!
Таблица поведения
| Значение | && | ?? |
|---|---|---|
true | true | true |
false | false | false |
0 | 0 | 0 |
'' (пусто) | '' | '' |
null | null | правое значение |
undefined | undefined | правое значение |
NaN | NaN | NaN |
Вывод
&& — логический оператор, проверяющий truthy/falsy значения. Возвращает первое falsy или последнее truthy значение.
?? — оператор нулевого слияния, проверяющий только null и undefined. Возвращает левое значение, если оно не null/undefined, иначе правое.
Выбор оператора зависит от контекста:
- Условный рендер и логические проверки —
&& - Значения по умолчанию —
??(если нужно сохранить falsy значения типа 0 или '')