跳转到主要内容
myfreax
返回

JavaScript 可选链接运算符 ?.

JavaScript 可选链接运算符 ?.

JavaScript 可选链接运算符 ?.

在本教程中,您将了解可选的链接运算符 ?.,它简化已连接对象的访问值的方式。

JavaScript 可选链运算符介绍

可选的链接运算符 ?. 允许您访问位于对象链深处的属性值,而无需显式检查链中的每个引用是否为null 或者是 undefined

如果链中的引用对象之一是 null 或者 undefined,则可选的链接运算符 ?. 将短路并返回 undefined

假设您有一个返回 user 对象的函数:

function getUser(id) {

    if(id <= 0) {
        return null;
    }

    // 获取用户从数据库
    // 如果用户不存在则返回null
    // ...
    
    // 如果用户找到,则返回用户
    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,使用逻辑运算符

let user = getUser(2);
let profile = user && user.profile;

在此示例中,我们确认 user 不是 undefinednull 之前访问 user.profile 属性的值。它可以避免直接访问 user.profile 引发的错误。

ES2020 引入可选的链接运算符,由问号后跟一个点表示:

?.

要使用可选的链接运算符访问对象的属性,您可以使用以下语法之一:

objectName ?. propertyName
objectName ?. [expression]

可选的链接运算符在尝试访问 user.profile 之前,隐式检查 user 是否是 nullundefined

let user = getUser(2);
let profile = user ?. profile;

在此示例中,如果 usernull 或者 undefined,则可选的链接运算符 ?. 会立即返回 undefined

从技术上讲,它等同于下面的语句:

let user = getUser(2);
let profile = (user !== null || user !== undefined)
            ? user.profile
            : undefined;

堆叠可选的链接运算符

如果 getUser() 返回的 user 对象没有 profile 属性。在不检查第一个的情况下尝试访问 user.profileavatar 属性将会导致错误。

为避免错误,您可以多次使用可选的链接运算符,如下所示:

let user = getUser(-1);
let avatar = user ?. profile ?. avatar;

在这种情况下,avatarundefined.

组合空值合并运算符

如果要将默认配置文件分配给 user,可以将可选的链接运算符 ?. 与空值合并运算符 ?? 组合使用,如下所示:

let defaultProfile =  { default: '/default.png', language: 'English'};

let user = getUser(2);
let profile = user ?. profile ?? defaultProfile;

在此示例中,如果 user.profilenull 或者是 undefined,则配置文件将因为空值合并运算符而采用 defaultProfile

在函数使用可选的链接运算符

假设您有一个文件 API,如下所示:

let file = {
    read() {
        return 'file content';
    },
    write(content) {
        console.log(`Writing ${content} to file...`);
        return true;
    }
};

本例调用 file 对象的 read() 方法:

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) {
    // 获取用户
    // ...

    let user = {
        id: id,
        username: 'admin'
    };

    // 判断回调是否存在
    if ( callback ) {
        callback(user);
    }

    return user;
}

通过使用可选的链接运算符,如果回调存在,您可以跳过判断:

function getUser(id, callback) {
    // 获取用户
    // ...

    let user = {
        id: id,
        username: 'admin'
    };

    // test if the callback exists
    callback ?. (user);


    return user;
}

结论

如果您尝试访问一个为 null 或者 undefined 的对象属性,可选的链接运算符 ?. 将返回 undefined 而不是抛出错误:。

将可选的链接运算符 ?. 与空值合并运算符 ?? 组合使用可以分配默认值。

functionName ?. (args) 用于在调用 functionName 之前,避免显式检查 functionName 是否存在undefinednull

myfreax

  1. 暂无评论,快来抢沙发吧!