В этом руководстве вы узнаете о необязательном операторе цепочки( ?. ) в JavaScript, который упрощает способ доступа к значениям через связанные объекты.
Необязательный оператор цепочки( ?. ) позволяет получить доступ к значению свойства, расположенного глубоко внутри цепочки объектов, без явной проверки того, является ли каждая ссылка в цепочке null или undefined.
Если одна из ссылок в цепочке null или undefined, необязательный оператор цепочки( ?. ) замкнется и вернет undefined.
Предположим, у вас есть функция, которая возвращает user объект:
function getUser(id) {
if (id & lt; = 0) {
return null;
}
// get the user from database
// and return null if id does not exist
// ...
// if user was found,
return the user
return {
id: id,
username: 'admin',
profile: {
avatar: '/avatar.png',
language: 'English'
}
}
}Следующий код использует getUser() для доступа к профилю пользователя:
let user = getUser(1); let profile = user.profile;
Однако, если вы передадите id, который меньше или равен нулю, или id не существует в базе данных, getUser() вернет значение null.
Поэтому перед обращением к свойству avatar нужно проверить, не является ли user null с помощью логического оператора AND:
let user = getUser(2); let profile = user && user.profile;
В этом примере мы подтверждаем, что user не является null или undefined, прежде чем получить доступ к значению свойства user.profile. Это предотвращает ошибку, которая могла бы возникнуть, если бы вы просто обращались к user.profile напрямую, не проверяя сначала пользователя.
ES2020 представил необязательный оператор цепочки, обозначаемый знаком вопроса, за которым следует точка:
?.
Чтобы получить доступ к свойству объекта с помощью необязательного оператора цепочки, вы используете один из следующих способов:
objectName ?. propertyName objectName ?. [expression]
Необязательный оператор цепочки неявно проверяет, не является ли user null или undefined, прежде чем пытаться получить доступ к user.profile :
let user = getUser(2); let profile = user ?. profile;
В этом примере, если user имеет значение null или undefined, необязательный оператор цепочки( ?. ) немедленно возвращает значение undefined.
Технически это эквивалентно следующему:
let user = getUser(2); let profile =(user !== null || user !== undefined) ? user.profile : undefined;
Стекирование
В случае, если user объект, возвращаемый getUser(), не имеет свойства profile. Попытка получить доступ к avatar без предварительной проверки user.profile приведет к ошибке.
Чтобы избежать ошибки, вы можете использовать необязательный оператор цепочки несколько раз, например:
let user = getUser(-1); let avatar = user ?. profile ?. avatar;
В этом случае avatar не undefined.
Комбинирование с нулевым оператором объединения
Если вы хотите назначить user профиль по умолчанию, вы можете комбинировать необязательный оператор цепочки( ?. ) с нулевым оператором объединения( ?? ) следующим образом:
let defaultProfile = { default: '/default.png', language: 'English'};
let user = getUser(2);
let profile = user ?. profile ?? defaultProfile;В этом примере, если user.profile имеет значение null или undefined, профиль примет значение defaultProfile из-за нулевого оператора объединения.
Использование с вызовами функций
Предположим, что у вас есть следующий файловый API:
let file = {
read() {
return 'file content';
},
write(content) {
console.log(`Writing $ {
content
}
to file...`);
return true;
}
};В этом примере вызывается метод read() объекта file :
let data = file.read(); console.log(data);
Если вы вызываете метод, который не существует в file объекте, вы получите TypeError :
let compressedData = file.compress();
Ошибка:
Uncaught TypeError: file.compress is not a function
Однако, если вы используете необязательный оператор цепочки с вызовом метода, выражение вернет undefined значение, а не выдаст ошибку:
let compressedData = file.compress?.();
compressedData теперь undefined.
Это полезно, когда вы используете API, в котором метод может быть недоступен по какой-либо причине, например, для определенного браузера или устройства.
Ниже показан синтаксис использования необязательного оператора цепочки с вызовом функции или метода:
functionName ?.(args)
Необязательный оператор цепочки( ?. ) также полезен, если у вас есть функция с необязательным обратным вызовом:
function getUser(id, callback) {
// get user
// ...
let user = {
id: id,
username: 'admin'
};
// test if the callback exists
if (callback) {
callback(user);
}
return user;
}Используя необязательный оператор цепочки, вы можете пропустить тест, если обратный вызов существует:
function getUser(id, callback) {
// get user
// ...
let user = {
id: id,
username: 'admin'
};
// test if the callback exists
callback ? . (user);
return user;
}Заключение
- Необязательный оператор цепочки(
?.) возвращаетundefinedвместо того, чтобы выдавать ошибку, если вы пытаетесь получить доступ к свойствуnullилиundefinedобъекта:obj ?. property. - Объедините необязательный оператор цепочки(
?.) с нулевым оператором объединения(??), чтобы назначить значение по умолчанию. - Используйте
functionName ?.(args), чтобы избежать явной проверки, не является лиfunctionNameundefinedилиnullперед его вызовом.
