前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >你可能不知道的 JS 特性:可选链

你可能不知道的 JS 特性:可选链

作者头像
savokiss
发布2019-12-17 17:50:30
1K0
发布2019-12-17 17:50:30
举报
文章被收录于专栏:码力全开

今天我们来介绍一个你可能没见过的 JS 新特性,目前处于 Stage 3 阶段,它叫作 可选链(optional chaining),它可能解决很多人都面对过的痛点,让我们来了解下~

为什么我们需要它

想象一下你从某个 api 获取数据,返回的对象嵌套了好多层,这就意味着你需要写很长的属性访问:

代码语言:javascript
复制
// API response object
const person = {
    details: {
        name: {
            firstName: "Michael",
            lastName: "Lampe",
        }
    },
    jobs: [
        "Senior Full Stack Web Developer",
        "Freelancer"
    ]
}
// Getting the firstName
const personFirstName = person.details.name.firstName;

上面的代码很容易产生错误,我们一般会这么改进:

代码语言:javascript
复制
// Checking if firstName exists
if( person &&
    person.details &&
    person.details.name ) {
        const personFirstName = person.details.name.firstName || 'stranger';
}

可以看到为了访问某个人的 firstName,代码变得非常不优雅。我们可以用 lodash 来优化一下:

代码语言:javascript
复制
_.get(person, 'details.name.firstName', 'stranger');

lodash 的写法可读性更高,但是需要引入额外的依赖,而且在团队内部大家可能不会统一都这么写,那么有没有更好的办法呢?

解决方案

可选链 就是为了解决这个问题而诞生的。

用法

可选链在语法上可能看起来比较陌生,但是用了几次之后你就会很容易适应这种写法。

代码语言:javascript
复制
const personFirstName = person?.details?.name?.firstName;

其实就是在属性访问符 . 的前面加了个问号。我们看上面语句中第一个 ?. ,从 JS 层面,它表示如果 person 的值为 null 或者 undefined,就不会报错而返回 undefined,否则才继续访问后面的 details 属性。而如果后面的属性访问链中有任何一个属性为 null 或者 undefined,那么最终的值就为 undefined

默认值

为了优雅地设置默认值,我们引入另外一个特性:空值合并运算符(nullish-coalescing-operator),听起来好像很复杂,其实也很简单:

代码语言:javascript
复制
const personFirstName = person?.details?.name?.firstName ?? 'stranger';

这个运算符就是 ??,如果它左侧表达式的结果是 undefinedpersonFirstName,就会取右侧的 stranger。 是不是跟短路运算符 || 很像,那假如我们把 ?? 换成 || 呢? 上面的例子中,如果 firstName 的值为 0 或者空字符串等非 undefinedfalsy 值,那么最终的结果就不一样了。 ?? 就是为了取代 || ,来做设置默认值这件事的。

动态属性

如果你需要使用动态属性,同样很简单:

代码语言:javascript
复制
const jobNumber = 1;
const secondJob = person?.jobs?.[jobNumber] ?? 'none';

上面的代码中, jobs?.[jobNumber]jobs[jobNumber] 的含义是一样的,区别就是前者不会报错。

函数或方法调用

同样的,如果想安全调用一个方法,只需要使用 ?.()

代码语言:javascript
复制
const currentJob = person?.jobs.getCurrentJob?.() ?? 'none';

如果 getCurrentJob 不是一个函数,currentJob 的值就是 none

现在就使用这个特性

很显然,这个特性的兼容性感人,不过没关系,我们有 babel! 立刻,马上就能让你使用它:

babel-plugin-proposal-optional-chaining

最后的话

这个特性在很多其他的语言如 C#Swift 中都有实现,并且 TypeScript 中也已经加入该特性。感兴趣的小伙伴还不快尝试一下,如果嫌安装 babel plugin 太麻烦,直接使用 lodash 的 get 也不失为一种保守的选择~

参考链接

JS new feature: Optional Chaining proposal-optional-chaining babel-plugin-proposal-optional-chaining babel nullish-coalescing-operator

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2019-12-09,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 码力全开 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 为什么我们需要它
  • 解决方案
    • 用法
      • 默认值
        • 动态属性
          • 函数或方法调用
            • 现在就使用这个特性
              • 最后的话
              • 参考链接
              领券
              问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档