「译」JS新特性“可选链式调用”
在JavaScript中长的链式调用可能容易出错,因为任何一步都可能出现null
或undefined
(也被称为“无效”值)。检查每个步骤的属性是否存在很容易变成深层次嵌套的if
声明或者复制属性访问链的长的if
条件:
|
|
以上还可以使用三元表达式,但是同样难以阅读:
|
|
介绍可选调用链
我们并不想写出这样的代码,所以有一些代替方案是可取的。一些语言(例如swift,具体查看https://www.jianshu.com/p/5599b422afb0)针对这个问题提供了优雅的解决方案——可选调用链。
根据最近的规范,“可选调用链是一个或多个属性访问和函数调用的链,以?.
开头”。
使用新的可选调用链,我们可以重写上面的demo:
|
|
使用可选调用链,当db
,user
,或name
是undefined
或者null
的时候,nameLength
被初始化为undefined
,而不是像之前那样抛出错误。
**Note:**可选调用链比我们自己用if(db && db.user && db.user.name)
检查更加健壮,例如,如果name
是一个空字符串,可选字符串会将name?.length
改为name.length
然后得到正确的长度0
,但是如果像我们之前那样做判断,不会得到正确的值,因为在if语句中空字符和false
的行为相同。可选调用链修复了这个常见的bug。
其他的语法形式:调用和动态属性
还有一个用于调用可选方法的运算符:
|
|
这个语法可能有点儿出乎意料,因为这里的运算符是?.()
,该运算符适用于之前的表达式。
可选调用链还有第三种用法,即可选动态属性访问?.[]
。如果对象中有该key对应的value,则返回value,否则返回undefined
。demo如下:
|
|
该用法同样适用于可选索引数组,例如:
|
|
可选调用链可以和nullish coalescing ?? 操作符结合使用,返回一个非undefined
的默认值。这样可以使用指定的默认值安全的进行深层属性访问,解决了之前用户需要JavaScript库才能解决的问题,例如lodash的_.get:
|
|
可选调用链的属性
可选调用链有一些有趣的属性:短路(short-circuiting),堆叠(stacking)和可选删除(optonal deletion)。下面通过例子来了解这些属性。
*短路(short-circuiting)*即如果可选调用链提前返回则不计算表达式的其余部分:
|
|
*堆叠(stacking)*意味着可以在一系列属性访问中应用多个可选调用运算符:
|
|
但是,考虑在一个链中使用多个可选调用运算符。如果一个value保证是有效的,那么不鼓励使用?.
去访问属性。像在之前的例子中,db
必然是定义的,但是db.users
和db.users[42]
可能是未定义的。如果数据库中有这样的用户,那么name.first.length
也是始终被定义的。
*可选删除(optonal deletion)*就是delete
操作符可以和可选链一起使用:
|
|
更多细节可以访问该提案的语义部分。
原文链接:https://v8.dev/features/optional-chaining