Необязательная цепочка(?.) – это оператор, который позволяет нам считывать свойство, расположенное на одном или нескольких уровнях в глубине цепочки связанных объектов, без необходимости проверки правильности каждой ссылки в цепочке. а не nullish.

Зачем нам это нужно?

Допустим, у нас есть объект с глубиной вложенности на один уровень, как показано ниже.

const product = {
  name: ‘Pencil’,
  properties: {
   color: ‘Red’,
   texture: ‘Smooth’,
  },
};

Нам легко получить доступ к свойству color для продукта. Но что, если нам нужно убедиться, что у нас есть свойство с именем properties внутри продукта, а затем вернуть color. Для этого в настоящее время мы можем использовать операторы conditional или использовать default value в качестве запасного варианта.

Пример условного доступа

let productColor;
if (product.properties) {
   productColor = product.properties.color;
}

Пример резервного значения по умолчанию

let productColor = (product.properties || {}).color;

Второй выглядит намного лучше, но что, если уровней вложенности много и нам нужно извлечь значение глубоко из этих связанных объектов??

Именно здесь необязательная цепочка поможет нам вернуть значение, только если каждая ссылка действительна. Если что-то промежуточное оценивается как null или undefined, выражение замкнется и вернет undefined. Необязательная цепочка также может использоваться для вызова функций, только если функция существует.

Совет. Какие еще языки имеют необязательную цепочку или аналогичную концепцию?

  • Руби имеет Safe navigation operator
  • С# имеетNull Conditional Operator
  • У Свифта Optional Chaining
  • Угловой имеет Safe navigation operator

Давайте теперь посмотрим на пример глубокой цепочки и на то, как необязательная цепочка поможет нам написать много условной логики и превратить ее в более читаемый и понятный формат.

const customer = {
  name: "Gopi",
  address: {
    street1: "135, MGR Street",
    street2: " Mylapore",   
    city: "Chennai",
    country: "India",
    contact: {
      mobile: "+91-974838XXXX",
      email: "[email protected]",
    },
  },
};

Рассмотрим приведенный выше пример простой детали клиента. Теперь скажем, нам нужно получить доступ к контактным данным, таким как mobile и email. Давайте посмотрим, как мы можем сделать это, используя optional chaining.

const customerMobile = customer?.address?.contact?.mobile || ‘No Mobile number specified’;
const customerEmail = customer?.address?.contact?.email || ‘No email specified’;

Идентификаторы customerMobile и customerEmail будут содержать фактическое значение мобильного телефона и электронной почты, или, если одно из значений в цепочке оценивается как nullish, будет возвращено значение как No Mobile number specified или No email specified соответственно.

Необязательная цепочка с функциональными вызовами

С появлением все большего количества объектно-ориентированного программирования и появлением компонентной архитектуры с такими фреймворками, как ReactJs, VueJs и т. д., появилось множество значений и функций, являющихся паролем как properties. В некоторых сценариях нам может понадобиться вызвать функцию, если она была нам передана. Здесь нам поможет необязательная цепочка.

Допустим, нам была передана функция, которую необходимо вызывать, когда пользователь выполняет определенные действия, такие как нажатие кнопки или сохранение и т. д. Обычно мы делаем что-то вроде ниже

if (this.props.onSave) {
 this.props.onSave(args);
}

Вместо описанного выше типа реализации мы можем реализовать это гораздо проще и плавнее, используя приведенный ниже синтаксис.

this.props.onSave?.(args);

Где можно использовать необязательную цепочку?

  • Доступ к глубоко вложенным объектам
let val = object1.property1.property2.value;
  • Чтобы вызвать функцию, если она существует
onError?.(arg1, arg2, ...etc);
  • Доступ к свойствам с помощью выражения
let value = obj?.[‘prop’ + ‘name’];
  • Доступ к элементу массива
let arrayItem = arr?.[93];

Возможность использования

Как обычно, большинство основных браузеров и последних версий уже реализовали это, за исключением Internet Explorer (как обычно). Также транспиляторы, такие как babel, поддерживают их, и не следует уклоняться от их использования.

Вы также можете увидеть эту таблицу поддержки браузеров на сайте canuse.com.

Вывод

Необязательный оператор цепочки определенно повысит читабельность кода и позволит нам писать гораздо меньший объем кода, устраняя необходимость в условной логике. При этом необязательные цепочки будут частью ES2021, и, следовательно, мы можем получить больше поддержки от браузеров с точки зрения их реализации.