?? - это оператор нулевого слияния (nullish coalescing), который подставляет значение справа только если слева null или undefined.
Он особенно полезен для значений по умолчанию, когда 0, false и пустая строка считаются нормальными и не должны заменяться.
Название может немного сбивать с толку: оператор не связан с числом 0. Здесь речь именно про значения null и undefined.
Синтаксис
left ?? right
Если left равен null или undefined, результатом будет right.
Во всех остальных случаях результатом будет left.
Что делает ??
Оператор проверяет левую часть только на null и undefined.
console.log(null ?? "default"); // "default"
console.log(undefined ?? "default"); // "default"
console.log("text" ?? "default"); // "text"
Это удобно, когда нужно сохранить нормальные falsy-значения, но всё же подставить дефолт для отсутствующего значения.
Что возвращает ??
?? не приводит результат к boolean. Он возвращает одно из исходных значений.
const value = 0 ?? 10;
console.log(value); // 0
console.log(typeof value); // "number"
Это значит, что оператор можно использовать не только со строками, но и с числами, объектами, массивами и любыми другими значениями.
null и undefined
Это два случая, для которых ?? действительно срабатывает.
console.log(null ?? "Guest"); // "Guest"
console.log(undefined ?? "Guest"); // "Guest"
Если значение пришло как null или undefined, оператор подставит запасной вариант справа.
0, false и пустая строка
Это ключевое отличие ?? от ||.
console.log(0 ?? 10); // 0
console.log(false ?? true); // false
console.log("" ?? "text"); // ""
Хотя эти значения являются falsy, они не считаются отсутствующими значениями, поэтому ?? их не заменяет.
NaN тоже не считается отсутствующим значением
Это ещё один важный нюанс:
console.log(NaN ?? 5); // NaN
NaN - это специальное числовое значение, но не null и не undefined.
Если нужно отдельно обрабатывать NaN, используют Number.isNaN().
?? и ||
Эти операторы часто путают, потому что оба могут подставлять значение по умолчанию.
const page = 0;
console.log(page || 1); // 1
console.log(page ?? 1); // 0
|| подставляет значение справа для любого falsy-значения:
0false""NaNnullundefined
?? подставляет значение справа только для:
nullundefined
Поэтому, если 0 и "" валидны, чаще лучше использовать именно ??.
?? и оператор опциональной цепочки
Очень часто ?? используют вместе с ?..
const user = {};
const city = user.profile?.address?.city ?? "Город не указан";
console.log(city); // "Город не указан"
Такой шаблон очень удобен:
?.безопасно читает значение??подставляет дефолт, если результат оказалсяnullилиundefined
Цепочка из нескольких ??
Оператор можно использовать несколько раз подряд.
console.log(null ?? undefined ?? "default"); // "default"
JavaScript будет брать первое значение, которое не равно null и не равно undefined.
Короткое замыкание
?? работает с коротким замыканием.
Если левое значение уже подходит, правая часть не вычисляется.
const name = "Sam";
console.log(name ?? "Guest"); // "Sam"
Правая часть здесь уже не нужна.
Когда это полезно
?? удобно использовать, когда:
- нужно подставить значение по умолчанию только для
nullиundefined 0,falseи""являются нормальными значениями- данные приходят из формы, API, localStorage или настроек
- код читается лучше через явную проверку на
nullиundefined, чем через общий falsy-подход
Пример:
function getPage(page) {
return page ?? 1;
}
console.log(getPage(0)); // 0
console.log(getPage(undefined)); // 1
Ограничение: нельзя смешивать с || и && без скобок
Это важное синтаксическое правило.
Так писать нельзя:
// null || undefined ?? "x"; // SyntaxError
// true && undefined ?? "x"; // SyntaxError
Нужно явно расставить скобки:
console.log((null || undefined) ?? "x"); // "x"
console.log(true && (undefined ?? "x")); // "x"
JavaScript специально требует скобки, чтобы не было путаницы в чтении выражения.
?? не работает с необъявленной переменной
Если переменная вообще не объявлена, ошибка произойдёт раньше.
// notDeclared ?? "x"; // ReferenceError
Оператор помогает только тогда, когда значение уже существует как переменная, но может быть null или undefined.
Частые ошибки
Использовать || там, где нужен ??
const count = 0;
console.log(count || 10); // 10
console.log(count ?? 10); // 0
Если 0 - допустимое значение, || даст неверный дефолт.
Думать, что ?? реагирует на все falsy-значения
console.log("" ?? "text"); // ""
console.log(false ?? true); // false
console.log(NaN ?? 5); // NaN
Оператор проверяет только null и undefined.
Смешивать ?? с || или && без скобок
// null || undefined ?? "x"; // SyntaxError
Нужны явные скобки.
Ожидать, что ?? спасёт от необъявленной переменной
// notDeclared ?? "x"; // ReferenceError
Если переменная не существует, ошибка будет раньше.
Быстрая памятка
left ?? rightвозвращаетrightтолько еслиleftравенnullилиundefined0,false,""иNaNне считаются отсутствующими значениями??часто удобнее||, когда falsy-значения допустимы- оператор возвращает одно из исходных значений без преобразования в boolean
??очень часто используют вместе с?.??нельзя смешивать с&&и||без скобок
Коротко
?? - это оператор JavaScript для подстановки значения по умолчанию только в случаях null и undefined. Главное, что стоит запомнить: он не заменяет 0, false и пустую строку, поэтому во многих прикладных сценариях подходит лучше, чем ||, особенно рядом с ?..