还在用三元表达式吗~链判断运算符满足你的需求
平时在我们的开发中遇到链式调用,经常会需要判空,防止代码取值报错。ES2020给我们提供了一个简单便捷的方法:“?.”,那么要怎么用呢,我们一起归纳一下。
为什么要用?.
代码编写中,需要从data中取item中的name的值,我们可以写成:data.item.name,但是这样是有风险的,如果data为空,则代码会报错。
- 判断也可以解决,写法为:
data&data.item&data.item.name
,但是这样代码太过于冗长 - 三元运算符也可以解决,写法为:
data.item?data.item.name:undefined
,判断层级比较低的结构还可以,如果层级比较高,和上面一条的判断方式的问题一样,同时更不易读写 - 链判断运算符对比起来更精简:
data?.item?.name
,如果左侧对象为null
或者undefined
,就不会再往下运算。
?.支持什么情况下使用
-
链式判断
data?.item?.name
-
方法调用判断
method?.(); //如果有这个方法,则调用、如果没有这个方法,则不作操作。
-
不同浏览器版本方法的适配
if (myForm.checkValidity?.() === false) { // 表单校验失败 return; } //对于一些低版本的浏览器,没有“checkValidity”这个方法,如果直接写会报错。利用?.判断,将方法转换成“undefined”,就不会执行这个方法了。
常见用法
-
主要有三种用法,后续扩展也是围绕着这三种
obj?.data
//判断属性是否存在obj?[data]
//判断属性是否存在(同上)method?.()
//判断方法是否存在
-
常用形式
a?.b
// 等同于
a == null ? undefined : a.b
a?.[x]
// 等同于
a == null ? undefined : a[x]
a?.b()
// 等同于
a == null ? undefined : a.b()
a?.()
// 等同于
a == null ? undefined : a()
使用时需要注意的点
-
短路机制
根据前面的研究可以得出:?.一旦判断满足条件,就不会继续向下执行。
-
括号的影响
一般情况下,在我们用?.的时候,是不会用圆括号的。如果链路有圆括号,则链路判断运算符对圆括号里有影响,对圆括号外没有有影响。看下面的例子
(a?.b).c; //?.仅仅对括号中有影响,括号外的取值不受影响
-
禁止使用的场景
//构造函数 new a?.(); new a?.b(); //链判断运算符的右侧有末班字符串 a?.`b`; a?.`${b}`; //链判断运算符左侧是super super?.(); super?.foo; //链运算符用于赋值运算符左侧 a?.b = c; //链运算符右侧不能是十进制数字 a?.3 //会被解析成:a? .3:0。