摘要: 在本教程中,您将了解可选链运算符 (?.),它简化了通过连接对象访问值的方式。
JavaScript 可选链运算符简介
可选链运算符 (?.) 就像一个访问对象系列中嵌套属性的快捷方式。 您无需检查链中每个步骤是否为空 (null 或 undefined),而是可以使用运算符 ?. 直接访问所需的属性。
如果链的任何部分为空,可选链运算符 (?.) 将立即停止并返回 undefined 作为结果。 它可以避免您为链中每个步骤编写额外的检查。
假设您有一个返回 user 对象的函数
function getUser(id) {
if(id <= 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'
}
}
}Code language: JavaScript (javascript)以下示例使用 getUser() 函数访问用户资料
let user = getUser(1);
let profile = user.profile;Code language: JavaScript (javascript)但是,如果您传递的 id 小于或等于零,或者 id 在数据库中不存在,getUser() 函数将返回 null。
因此,在访问 avatar 属性之前,您需要使用 逻辑运算符 AND 检查 user 是否不为 null
let user = getUser(2);
let profile = user && user.profile;Code language: JavaScript (javascript)在此示例中,我们确认 user 不为 null 或 undefined,然后才访问 user.profile 属性的值。 它可以防止在未首先检查用户的情况下直接访问 user.profile 时出现的错误。
ES2020 引入了可选链运算符,它由问号后跟一个点表示
?.Code language: JavaScript (javascript)要使用可选链运算符访问对象的属性,请使用以下方法之一
objectName ?. propertyName
objectName ?. [expression]Code language: JavaScript (javascript)可选链运算符隐式地检查 user 是否不为 null 或 undefined,然后才尝试访问 user.profile
let user = getUser(2);
let profile = user ?. profile;Code language: JavaScript (javascript)在此示例中,如果 user 为 null 或 undefined,可选链运算符 (?.) 将立即返回 undefined。
从技术上讲,它等效于以下内容
let user = getUser(2);
let profile = (user !== null || user !== undefined)
? user.profile
: undefined;
Code language: JavaScript (javascript)堆叠可选链运算符
如果 getUser() 返回的 user 对象没有 profile 属性,则在没有先检查 user.profile 的情况下尝试访问 avatar 将导致错误。
为了避免错误,您可以多次使用可选链运算符,如下所示
let user = getUser(-1);
let avatar = user ?. profile ?. avatar;Code language: JavaScript (javascript)在这种情况下,avatar 为 undefined。
与空值合并运算符结合使用
如果您想为 user 指定默认资料,可以将可选链运算符 (?.) 与空值合并运算符 (??) 结合使用,如下所示
let defaultProfile = { default: '/default.png', language: 'English'};
let user = getUser(2);
let profile = user ?. profile ?? defaultProfile;Code language: JavaScript (javascript)在此示例中,如果 user.profile 为 null 或 undefined,由于空值合并运算符的存在,资料将采用 defaultProfile
将可选链运算符与函数调用结合使用
假设您有一个文件 API,如下所示
let file = {
read() {
return 'file content';
},
write(content) {
console.log(`Writing ${content} to file...`);
return true;
}
};Code language: JavaScript (javascript)此示例调用 file 对象的 read() 方法
let data = file.read();
console.log(data);Code language: JavaScript (javascript)如果您调用 file 对象中不存在的方法,您将收到 TypeError
let compressedData = file.compress();Code language: JavaScript (javascript)错误
Uncaught TypeError: file.compress is not a functionCode language: JavaScript (javascript)但是,如果您将可选链运算符与方法调用一起使用,表达式将返回 undefined 而不是抛出错误
let compressedData = file.compress?.();Code language: JavaScript (javascript)现在 compressedData 为 undefined。
这在您使用 API 时很有用,在该 API 中,方法可能由于某种原因不可用,例如特定浏览器或设备。
以下示例说明了将可选链运算符与函数或方法调用一起使用的语法
functionName ?. (args)Code language: JavaScript (javascript)可选链运算符 (?.) 在您有一个带可选 回调 的函数时也很有用
function getUser(id, callback) {
// get user
// ...
let user = {
id: id,
username: 'admin'
};
// test if the callback exists
if ( callback ) {
callback(user);
}
return user;
}Code language: JavaScript (javascript)通过使用可选链运算符,您可以跳过回调是否存在时的测试
function getUser(id, callback) {
// get user
// ...
let user = {
id: id,
username: 'admin'
};
// test if the callback exists
callback ?. (user);
return user;
}Code language: JavaScript (javascript)总结
- 可选链运算符 (
?.) 在您尝试访问null或undefined对象的属性时返回undefined,而不是抛出错误:obj ?. property。 - 将可选链运算符 (
?.) 与空值合并运算符 (??) 结合使用,以指定默认值。 - 使用
functionName ?. (args)避免在调用functionName之前显式检查它是否不为undefined或null。