专栏首页码力全开你可能不知道的 JS 特性:可选链

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

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

为什么我们需要它

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

// 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;

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

// Checking if firstName exists
if( person &&
    person.details &&
    person.details.name ) {
        const personFirstName = person.details.name.firstName || 'stranger';
}

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

_.get(person, 'details.name.firstName', 'stranger');

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

解决方案

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

用法

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

const personFirstName = person?.details?.name?.firstName;

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

默认值

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

const personFirstName = person?.details?.name?.firstName ?? 'stranger';

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

动态属性

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

const jobNumber = 1;
const secondJob = person?.jobs?.[jobNumber] ?? 'none';

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

函数或方法调用

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

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

本文分享自微信公众号 - 码力全开(codingonfire),作者:savokiss

原文出处及转载信息见文内详细说明,如有侵权,请联系 yunjia_community@tencent.com 删除。

原始发表时间:2019-12-09

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • webpack 小技巧:动态批量加载文件

    作为一个有代码洁癖的程序员,我是不允许这种重复性代码存在滴,于是乎就尝试有没有什么简单的方法。

    savokiss
  • 带你理解 Git 中的 Merge 和 Rebase

    Rebase 和 merge 都被设计用来将变更从一个分支整合到另一个分支,但是它们的实现方式却不同。

    savokiss
  • 图解你身边的 SOLID 原则 - JS 实例版

    过了两天发现有人为那篇文章补充了 JavaScript 例子,看了下例子还不错,这次就顺便也翻译一下哈,部分例子有删改~

    savokiss
  • 【译】Javascript中你需要知道的最出色的新特性:Optional Chaining

    对于使用Javascript的每个人来说,可选链(Optional chaining)是游戏的规则的改变者。它与箭头函数或let和const一样重要。我们讨论下...

    嘉明
  • jQuery 图片轮播的代码分离

    以前遇到过jQuery实现列表自动滚动,这次的图片轮播在原理上与之相同,只有一些细微的差别,就是需要在图片的右下角显示当前图片的序号。

    小小许
  • 央视调查:机会和财富都去哪儿了

    大数据文摘
  • python3 GUI

    参考一:https://www.cnblogs.com/monsteryang/p/6558904.html 参考二:https://blog.csdn.n...

    py3study
  • 数据库结构版本控制

    数据库结构版本控制 http://netkiller.github.io/journal/mysql.struct.html 摘要 ---- 目录 1. 什么是...

    netkiller old
  • 使用JDBC操作SAP云平台上的HANA数据库

    本文假设您对JDBC(Java Database Connectivity)有最基本的了解。您也可以将其同ADBC(ABAP Database Connecti...

    Jerry Wang
  • 【PAT甲级】A+B and C (64bit)

    版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。 ...

    喜欢ctrl的cxk

扫码关注云+社区

领取腾讯云代金券