Необязательный оператор цепочки (?.) в JavaScript

В этом руководстве вы узнаете о необязательном операторе цепочки( ?. ) в 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), чтобы избежать явной проверки, не является ли functionName undefined или null перед его вызовом.
Рейтинг
( Пока оценок нет )
Александр Русаков / автор статьи
Программист, разработчик, 12 лет опыта работы в крупных компаниях. Быстро освоил typescript, делюсь своими знаниями на страницах этого сайта.
Загрузка ...
JavaScript и TypeScript