Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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

Open
reng99 opened this issue Sep 22, 2019 · 0 comments
Labels
blog a single blog javascript javascript tag

Comments

@reng99
Copy link
Owner

reng99 commented Sep 22, 2019

对于使用Javascript的每个人来说,可选链(Optional chaining)是游戏的规则的改变者。它与箭头函数或letconst一样重要。我们讨论下它可以解决什么问题,它如何工作,以及它如何使得你的生活更加轻松。

问题

想象以下场景:

你正在使用片段代码来从一个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';
}

正如示例中你所看到的,即使是简单的事情,比如获取一个人的名字,也很难正确获取。

所以,这就是为什么我们使用类似lodash库去处理这样的事情:

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

lodash使得代码更具可读性,但是你得在你的代码库中引入很多的依赖。你需要更新它,然后,如果你在一个团队中工作,你需要在团队中推广使用它。所以,这也不是一个理想的解决方案。

解决方案

可选链为这些(除了团队的问题)提供了一个解决方案。

它是怎么工作的

初次看到可选链的新语法,你可能会感到陌生,但是,几分钟后你会习惯它的。

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

好了,现在你脑子可能有很多问号(双关语义)。上面语法的?是个新的事物。这就是你要想想的地方了。在属性前(原文应该改为属性后比较准确)有?.,就是在问你属性person存在吗?或者,更加javascript的表达方式--person属性的值是nullundefined吗?如果是,将不会返回一个错误,而是返回undefined。所以personFirstName将返回undefined。对details?name?会进行重复的询问。如果任意一个的值为nullundefined,之后personFirstName都会返回undefined。这被称为Short-circuiting(短路)。一旦javascript找到值为nullundefined,它就会短路并不会再深入查询下去。

默认值

我们还需要学学Nullish coalescing operator(空位合并运算符)。好吧,这听起来很难学。但是实际上,一点也不难。我们看看下面的例子:

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

Nullish coalescing operator??来表示。它也很容易去解读。如果??左侧返回的内容是undefined,那么personFirstName会将??右侧的值赋值给它。这太容易了。

动态属性

有时候你需要获取动态的值。它可能是一个数组的值,或者是一个对象的动态属性。

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

这里需要重点理解的地方是jobs?.[jobNumber],它和jobs[jobNumber]表达的一样,但是不会抛出一个错误;相反,它会返回none值。

函数或方法调用

有时候,你会处理对象,而你不知道它们是否带有方法。这里我们可以使用?.()语法或带参数?.({ some: 'args'})语法。它会根据你的需求运行。如果在那个对象中不存在这个方法,它会返回值undefined

const currentJob = person?.jobs.getCurrentJob?.() ?? 'none';

上面的例子中,如果没有getCurrentJob方法,那么currentJob将会返回none

今天开始使用它

目前没有浏览器支持此功能--Babel做转换了。

这里已经有一个babel.js插件,如果你已经有了Babel设置,那就很容易集成了。

babel-plugin-proposal-optional-chaining

参考和后话

@reng99 reng99 added javascript javascript tag blog a single blog labels Sep 22, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
blog a single blog javascript javascript tag
Projects
None yet
Development

No branches or pull requests

1 participant