在本教程中,您将了解可选的链接运算符 ?.
,它简化已连接对象的访问值的方式。
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
不是 undefined
或 null
之前访问 user.profile
属性的值。它可以避免直接访问 user.profile
引发的错误。
ES2020 引入可选的链接运算符,由问号后跟一个点表示:
?.
要使用可选的链接运算符访问对象的属性,您可以使用以下语法之一:
objectName ?. propertyName
objectName ?. [expression]
可选的链接运算符在尝试访问 user.profile
之前,隐式检查 user
是否是 null
或 undefined
:
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;
堆叠可选的链接运算符
如果 getUser()
返回的 user
对象没有 profile
属性。在不检查第一个的情况下尝试访问 user.profile
的 avatar
属性将会导致错误。
为避免错误,您可以多次使用可选的链接运算符,如下所示:
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;
}
};
本例调用 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
是否存在undefined
或null
。