This page was translated from English by the community.Learn more and join the MDN Web Docs community.
Оператор опциональной последовательности
Baseline Widely available
This feature is well established and works across many devices and browser versions. It’s been available across browsers since июль 2020 г..
Операторопциональной последовательности?. позволяет получить значение свойства, находящегося на любом уровне вложенности в цепочке связанных между собой объектов, без необходимости проверять каждое из промежуточных свойств в ней на существование.?. работает подобно оператору., за исключением того, что не выбрасывает исключение, если объект, к свойству или методу которого идёт обращение, равенnull илиundefined. В этих случаях он возвращаетundefined.
Таким образом, мы получаем более короткий и понятный код при обращении к вложенным по цепочке свойствам объекта, когда есть вероятность, что какое-то из них отсутствует.
In this article
Интерактивный пример
const adventurer = { name: "Alice", cat: { name: "Dinah", },};const dogName = adventurer.dog?.name;console.log(dogName);// Expected output: undefinedconsole.log(adventurer.someNonExistentMethod?.());// Expected output: undefinedСинтаксис
obj?.prop;obj?.[expr];arr?.[index];func?.(args);Описание
Оператор опциональной последовательности предоставляет способ упростить доступ к значениям в цепочке объектов, когда возможно, что какое-то свойство (или метод) в ней равноundefined илиnull.
Для примера, создадим объектobj, имеющий вложенную структуру. Без оператора опциональной последовательности поиск глубоко расположенных подсвойств требует проверки всех промежуточных свойств на существование, например:
let nestedProp = obj.first && obj.first.second;Если обращаться кobj.first.second без проверкиobj.first, то, если свойствоobj.first равноnull илиundefined, выбросится исключениеTypeError.
Однако, с оператором опциональной последовательности (?.) не требуется явно проверять ссылку наobj.first перед обращением кobj.first.second:
let nestedProp = obj.first?.second;Если используется оператор?. вместо., JavaScript знает о необходимости проверкиobj.first перед обращением кobj.first.second. Если значениеobj.first равноnull илиundefined, выполнение выражения автоматически прекращается и возвращаетсяundefined.
Это эквивалентно следующему (кроме создания временной переменной):
let temp = obj.first;let nestedProp = temp === null || temp === undefined ? undefined : temp.second;Опциональная последовательность с вызовом функции
Вы можете использовать?., когда необходимо вызвать метод, которого может не существовать. Это может быть полезно, например, при использовании API, в котором метод может быть недоступен из-за устаревания или не поддерживаемости устройством пользователя.
Использование?. с вызовом функции значит, что выполнение автоматически вернётundefined, а не выбросит исключение, если метод не найден:
let result = someInterface.customMethod?.();Примечание:Для существующего свойства, не являющегося функцией, использование конструкцииx.y?.() всё равно выброситTypeError исключение (x.y не является функцией).
Работа с колбэк-функциями и обработчиками событий
Если вы используете колбэк-функции или извлекаете методы объектадеструктурирующим присваиванием, Вы можете получить несуществующие значения, которые нельзя вызывать как функции до проверки на их существование. Используя оператор?., вы можете избежать лишних проверок:
// С использованием ES2019function doSomething(onContent, onError) { try { // ... делаем что-то с данными } catch (err) { if (onError) { // проверяем, существует ли onError onError(err.message); } }}// С использованием оператора опциональной последовательностиfunction doSomething(onContent, onError) { try { // ... делаем что-то с данными } catch (err) { onError?.(err.message); // не выбросит исключение, если onError равен undefined }}Опциональные последовательности в выражениях
Вы также можете использовать оператор опциональной последовательности, когда обращаетесь к свойству с помощьюскобочной нотации:
let nestedProp = obj?.["prop" + "Name"];Примеры
>Базовый пример
В этом примере производится обращение к свойствуname элемента с ключомbar объектаMap. Элемент с таким ключом отсутствует, но исключение выброшено не будет;nameBar равенundefined.
let myMap = new Map();myMap.set("foo", { name: "baz", desc: "inga" });let nameBar = myMap.get("bar")?.name;Сокращённое выполнение
При использовании оператора опциональной последовательности в выражениях, где левая часть операнда равнаnull илиundefined, выражение не будет выполнено. Например:
let potentiallyNullObj = null;let x = 0;let prop = potentiallyNullObj?.[x++];console.log(x); // 0, т.к. x не был инкрементированСовместное использование операторов опциональной последовательности
Во вложенных объектах возможно использование оператора опциональной последовательности неограниченное количество раз:
let customer = { name: "Carl", details: { age: 82, location: "Paradise Falls", // точный адрес неизвестен },};let customerCity = customer.details?.address?.city;// … это также работает с вызовами функцийlet duration = vacations.trip?.getTime?.();Использование с оператором ??
Оператор?? может использоваться после опциональной последовательности для установления значения по умолчанию:
let customer = { name: "Carl", details: { age: 82 },};const customerCity = customer?.city ?? "Unknown city";console.log(customerCity); // Unknown cityСпецификации
| Specification |
|---|
| ECMAScript® 2026 Language Specification> # prod-OptionalExpression> |