lostvita / blog

60 stars 47 forks source link

TC39提案:可选链运算符 #16

Open lostvita opened 5 years ago

lostvita commented 5 years ago

原文:tc39/proposal-optional-chaining

更多:github

引言

什么是TC39?

Technical Committee 39,是ECMA下的技术委员会第39号,致力于推动JavaScript发展

TC39的提案流程

Stage 0:“稻草人”提案,包含任何尚未正式作为正式提案的讨论、想法。由TC39成员提交;

Stage 1:正式提交的提案,提供详细的语法、API描述和用例,并解决潜在问题;

Stage 2:将提案规范为草案,与最终形成的标准差异不大;

Stage 3:草案进入候选阶段,获得实现与用户反馈;

Stage 4:完成验收测试,提案中的特性进入下一个ECMAScript版本。

概述

提案阶段:Stage 2

作者:Claude Pache、Gabriel Isenberg、Dustin Savery

当我们在一个深层的树状结构的对象中查找属性值时,通常需要检查中间节点是否存在:

var street = user.address && user.address.street

此外,许多的API会返回一个对象或null/undefined,我们可能需要当结果值不为空的时候从中提取某个属性:

var fooInput = myForm.querySelector('input[name=foo]')
var fooValue = fooInput ? fooInput.value : undefined

可选链操作符允许开发者在不需要重复自身变量或者借助临时变量保存中间结果值的情况下处理这些情况:

var street = user.address?.street
var fooValue = myForm.querySelector('input[name=foo]')?.value

当属性值不存在,而我们又需要一个默认值时,可以通过空值合并去处理:

// 目前我们可能使用 const a = val || 0
const animationDuration = response.settings?.animationDuration ?? 300;

可选链运算符的调用变形对于处理具有可选方法的接口非常有用:

iterator.return?.() // 手动关闭迭代器

或者某个方法还没被实现时:

if (myForm.checkValidity?.() === false) {
    return;
}

语法

可选链的运算符拼写是 ?.,它可能出现在三个位置:

obj?.prop       // 访问静态属性
obj?.[expr]     // 访问动态属性
func?.(...args) // 方法调用

注意: 为了能够将 foo?.3:0 解析为 foo ? .3 : 0 ,规定如果 ?. 紧跟的是十进制数字,那么 ?. 不会被解析为单一的运算符,而是按照三元运算符进行处理。因此,要使用 ?. 运算符,其后不能紧跟十进制数字。

应用

基础案例: 短路机制:

如果 ?. 左边表达式的值为null/undefined,其右边的表达式就不会执行,这就是短路机制。

叠加使用:

一个可选链后面可能会跟着其他的可选链

边界情形:分组

使用圆弧括号限制短路的作用范围

delete操作符: 当尝试使用delete删除一个不存在的属性时,通常会返回一个true

结语

该运算符以及空值合并可以很大程度上简化我们的代码量,也能在一定程度上避免can not read property xxx of undefined的错误,可以期待下!