1

如果大家阅读过我之前写的一篇关于ES6解构的文章,那一定会了解到解构达到数据防御功能,那么本文要介绍的是另一种数据防御方式Optional Chaining(可选链)。

什么是Optional Chaining

Optional Chaining允许我们检查对象是否存在,然后才试图访问它的属性。其他编译语言也有类似的功能,如C#的 Null-conditional operator

为什么我们需要Optional Chaining

在访问对象或数组之前,您是否曾经检查过它的属性?如果你不检查,你可能会遇到以下问题:

if (a && a.b && a.b.length > 0) {
    console.log('666');
}

之所以执行这些检查,是因为 JavaScript的对象不需要事先声明结构或schema。因此,如果不判断他的父级是否为一个对象就开始访问其属性可能会遇到错误:
图片描述
当b为undefined时就报错了。

Optional Chaining 可以解决什么问题呢?

如果使用 Optional Chaining ,代码竟然可以如此简洁:

if (a?.b?.length > 0) {
    console.log('666');
}

怎么样? 告别了繁琐各种 & 和 各种层层检查,这又是一股清流。
但是,请记住可选的链接操作符是?.不是? 这意味着当你访问数组其中一个元素时,应该这样:

const firstItem = a?.b?.[0]; // right
const firstItem = a?.b?[0]; // wrong

同样地,如果你要访问一个函数时,应该这样:

const execFunc = a?.func?.(); // right
const execFunc = a?.func?(); // wrong

更多玩法

除了数据防御,Optional Chaining 还可以使用在更多的场景中:
判断并执行函数

a?.();
// 等价于
a == null ? undefined : a();
// 等价于
a && a();

条件执行

a?.[++x];
// 等价于
a == null ? undefined : a[++x];
a?.b.c(++x).d;
// 等价于
a == null ? undefined : a.b.c(++x).d;

更加复杂的嵌套

a?.b[3].c?.(x).d
// 等价于
a == null ? undefined : a.b[3].c == null ? undefined : a.b[3].c(x).d;
// 注:嵌套一出来无论怎么写,感觉可读性不强了,所以,别炫技。

也可以分组,可读性更强

(a?.b).c;
// 等价于
(a == null ? undefined : a.b).c;

删除对象中的属性

delete a?.b
// 等价于
a == null ? undefined : delete a.b

Optional Chaining 是如何工作的?

?.先判断他的Left-Hand-Side 是否是nullundefined,如果是,那么此表达式短路并返回 undefined,否则,表达式依次类推执行到最后。

如何使用?

Optional Chaining目前在Stage 1阶段。 在使用之前,大家可以先到这里体验一波: codepan
虽然目前Optional Chaining 是草案,但可以通过 Babel 插件 babel-plugin-syntax-optional-chaining 来尝鲜。

参考资料

proposal-optional-chaining


zzbo
114 声望6 粉丝