Оператор ?.

Последнее обновление: 24.10.2023

Оператор ?. или optional chaning-оператор позволяет проверить объект и его свойства и методы на null и undefined, и если объект или его свойства/методы определены, то обратиться к его свойствам или методам:

const tom = null;
const bob = {name: "Bob"};

function printName(person){
	console.log(person.name);
}
printName(tom);	// Uncaught TypeError: Cannot read properties of null (reading "name")
printName(bob);

В данном случае переменная tom равна null, соответственно у ней нет свойства name. Соответственно при передаче этого объекта в функцию printName мы получим ошибку. В этом случае мы можем перед обращением к объекту проверять его на null и undefined:

const tom = null;
const bob = {name: "Bob"};

function printName(person){
	if(person !==null && person !==undefined) console.log(person.name);
}
printName(tom);	
printName(bob);	// Bob

Также мы можем сократить проверку:

function printName(person){
	if(person) console.log(person.name);
}

Если person равен null или undefined, то if(person) возвратит false.

Однако оператор ?. предлагает более элегантный способ решения:

const tom = null;
const bob = {name: "Bob"};

function printName(person){
	console.log(person?.name);
}
printName(tom);	// undefined
printName(bob);	// Bob

После названия объекта указывается оператор ?. - если значение не равно null и undefined, то идет обращение к свойству/методу, которые указаны после точки. Если же значени равно null/undefined, то обращения к свойству/методу не происходит. И на консоли мы увидим undefined.

Данный оператор можно использовать перед обращением как к свойствам, так и к методам объекта:

const tom = undefined;
const bob = {
	name: "Bob", 
	sayHi(){
		console.log(`Hi! I am ${this.name}`);
	}
};

console.log(tom?.name);	// undefined
console.log(bob?.name);	// Bob
tom?.sayHi();			// не выполняется
bob?.sayHi();			// Hi! I am Bob

В данном случае обращение к свойству name и методу sayHi() происходит только в том случае, если объекты tom и bob не равны null/undefined.

Более того далее по цепочке вызывов проверять наличие свойства или метода в объекте.

obj.val?.prop		// проверка свойства
obj.arr?.[index]	// провера массива
obj.func?.(args)	// проверка функции

Проверка свойства

Объект может быть определен, однако не иметь какого-то свойства:

const tom = { name: "Tom"};
const bob = {
	name: "Bob", 
	company: {
		title: "Microsoft"
	}
};

console.log(tom.company?.title);	// undefined
console.log(bob.company?.title);	// Microsoft

Подобным образом мы можем обращаться к свойствам объекта с помощью синтаксиса массивов:

const tom = { name: "Tom"};
const bob = {
	name: "Bob", 
	company: {
		title: "Microsoft"
	}
};

console.log(tom.company?.["title"]);	// undefined
console.log(bob.company?.["title"]);	// Microsoft

Проверка свойства-массива

Аналогично мы можем проверять наличие свойства-массива перед обращением к его элементам:

const tom = { name: "Tom"};
const bob = {
	name: "Bob", 
	languages: ["javascript", "typescript"]
};

console.log(tom.languages?.[0]);	// undefined
console.log(bob.languages?.[0]);	// javascript

Проверка метода

Объект также может не иметь вызываемого у него метода. Если метод не определен, то при обращении к неопределенному методу мы столкнемся с ошибкой, и в этом случае также можно проверять наличие метода:

const tom = { name: "Tom"};
const bob = {
	name: "Bob", 
	say(words){
		console.log(words);
	}
};

console.log(tom.say?.("my name is Tom"));	// undefined
console.log(bob.say?.("my name is Bob"));	// my name is Bob

Цепочка проверок

С помощью оператора ?. можно создавать цепочки проверок, последовательно проверяя, представляет ли значение null/undefined:

const sam = {name: "Sam"};
const tom = { 
	name: "Tom", 
	company: { title: "Google"}
};
const bob = {
	name: "Bob", 
	company: {
		title: "Microsoft",
		print(){
			console.log(`Компания ${this.title}`)
		}
	}
};
sam?.company?.print?.();	// не вызывается - нет свойства company
tom?.company?.print?.();	// не вызывается - нет метода print
bob?.company?.print?.();	// Компания Microsoft
Помощь сайту
Юмани:
410011174743222
Перевод на карту
Номер карты:
4048415020898850