大家好,我是半夏👴,一个热爱分享的前端程序员(半吊子后端程序员).如果喜欢我的文章,可以关注➕ 点赞 👍 加我微信:frontendpicker,一起学习交流前端,成为更优秀的工程师~关注公众号:搞前端的半夏,免费更多前端知识!
对于javaScript开发者都会遇到一个问题:访问一个可选的子属性需要额外的逻辑来测试它是否存在。
例如,我们有一个article对象,其包含一个名为relatedArticle的对象属性,这个字段主要是用来保存相关文章的一些信息,假设我们通过以下方式访问相关文章的 URL
article.relatedArticle.url
然而,并非每篇文章都有相关文章,这种情况下则会报错:
Cannot read properties of undefined (reading 'url')
所以说我们先需要判断相关文章是否存在!
let article = {};
let url;
if(article.relatedArticle !== undefined) {
url = article.relatedArticle.url;
}
或者我们可能会想尝试这样的写法:
let article = {}
let url = article.relatedArticle ? article.relatedArticle : undefined;
但是,如果我们有多个子级别,我们最终可能会编写很长的undefined语句串。例如,下面我们article.relatedArticle.url.rootDomain在不确定这些对象是否会被定义时尝试访问:
let article = {};
let rootDomain;
if(article.relatedArticle !== undefined && article.relatedArticle.url !== undefined) {
rootDomain = article.relatedArticle.url.rootDomain;
}
可选链解决了过多逻辑检查的问题,如果某个东西被赋予了一个可选?.标签,那么如果它存在,则该值将被返回——否则它不会抛出错误。在上面的例子中,我们甚至不再需要一个if语句了:
let article = {};
let rootDomain = article.relatedArticle?.url?.rootDomain;
如何在 Javascript 中使用可选链
在大多数示例中,可以使用如上所述的可选链,以避免对象中可选的属性出现错误:
let article = {};
let rootDomain = article.relatedArticle?.url?.rootDomain;
需要注意的是,我们不能在对象的末尾添加?
let article = {};
let rootDomain = article.relatedArticle?.url?.rootDomain?;
// Will throw an error like `Unexpected t oken ';'`
可选链在函数中的应用
可以将可选链接与您期望可能返回对象的函数一起使用。它的工作方式与之前完全相同,只是我们?.在函数之后添加 - myFunction(…arguments)?.x:
let myFunction = (x, y, z) => {
if(z !== undefined) {
return {
x: x,
y: y,
z: z
}
}
}
let arguments = [ 1, 2, 3 ];
let getX = myFunction(...arguments)?.x;
console.log(getX); // Returns 1;
默认情况下,如果一个函数没有return,它会返回undefined——所以这在你不确定一个函数是否会返回任何东西的情况下非常有用。
可选链在数组中的应用
可选链接也可以与数组一起使用。例如 - 如果你不确定对象中是否存在一个数组属性。下面,用户可以拥有一组有效地址,我们希望从他们的第一个地址获取他们地址的第一行。由于它可能并不总是存在,我们可以在这里使用可选链接来尝试访问它。
let myUser = {
name: "John Doe",
age: 155
}
let getAddress = myUser.addresses?.[0]?.first
可选链在函数中的应用
有时,对象的属性可能返回一个函数。在这些情况下,我们可能想要运行这个函数,但由于它并不总是被定义,我们只希望在它存在时可以调用。在这种情况下,我们可以使用符号?.()来运行该函数。考虑以下示例:
let myObject = [
{
id: 15,
adder: (x) => {
return x + 10;
}
},
{
id: 145,
}
]
myObject.forEach((item) => {
let runFunction = item.adder?.(10) || 10;
console.log(runFunction);
});
上面,我们有一个包含数组的对象,其中每个对象都包含一个 id ,并且还可能包含 function adder。在这个例子中,如果它存在,我们想运行这个函数,或者如果函数未定义,则返回一个默认值10
let runFunction = item.adder?.(10) || 10;
在这里,如果adder定义了,它就会运行,所以我们得到x + 10 ,对于数组的第一个元素得到结果是20,对于第二个元素,因为adder不存在,得到的默认的返回值10。
总结
可选链非常有用,并且得到广泛支持(不包括 Internet Explorer)。它几乎可以与属性、数组或函数的任意组合一起使用,具体取决于返回类型。例如:
- obj?.property
- obj?.[property]
- obj[index]?.property
- obj?.(args)
- func(args)?.property