--- title: "Оператор\_опциональной последовательности" slug: Web/JavaScript/Reference/Operators/Optional_chaining translation_of: Web/JavaScript/Reference/Operators/Optional_chaining ---
Оператор опциональной последовательности ?.
позволяет получить значение свойства, находящегося на любом уровне вложенности в цепочке связанных между собой объектов, без необходимости проверять каждое из промежуточных свойств в ней на существование. ?.
работает подобно оператору .
, за исключением того, что не выбрасывает исключение, если объект, к свойству или методу которого идёт обращение, равен {{jsxref("null")}} или {{jsxref("undefined")}}. В этих случаях он возвращает 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
, выбросится исключение {{jsxref("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?.()
всё равно выбросит {{jsxref("TypeError")}} исключение (x.y не является функцией
).
Если вы используете колбэк-функции или извлекаете методы объекта деструктурирующим присваиванием, Вы можете получить несуществующие значения, которые нельзя вызывать как функции до проверки на их существование. Используя оператор ?.
, вы можете избежать лишних проверок:
// С использованием ES2019 function 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?.();
Оператор {{JSxRef("Operators/Nullish_Coalescing_Operator", "??", '', 1)}} может использоваться после опциональной последовательности для установления значения по умолчанию:
let customer = { name: "Carl", details: { age: 82 } }; const customerCity = customer?.city ?? "Unknown city"; console.log(customerCity); // Unknown city
{{Compat}}