Javascript 可选链

大家好,我是半夏👴,一个热爱分享的前端程序员(半吊子后端程序员).如果喜欢我的文章,可以关注➕ 点赞 👍 加我微信: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
  • 51
    点赞
  • 63
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

YOLO大王

你的打赏,我的动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值