前言
可选链?.
属于一种安全的访问对象属性的方式,即使在在嵌套对象中出现不存在的属性也不会出现错误。
访问嵌套对象问题
我们编写程序时总会出现一个对象中存在可能会是空值或者不存在的对象属性,而我们直接访问它的时候就会出现报错,如下代码
letobj={username:"花花",data:{age:18,height:170,weight:90,}}//正常输出,没问题console.log("第一次输出:"+obj.data.height)//当obj.data=null的时候就会出现以下错误obj.data=nullconsole.log("第二次输出:"+obj.data.height)
当data不存在,或者data等于Null,或者data等于undefined,都会存在上述问题。
解决方案 - 条件判断
为了解决上述问题最容易想到的就是通过条件判断来防止错误的发生。如下所示
obj={username:"花花",data:null}if(obj.data){console.log("正常输出:"+obj.data.height)}else{console.log("无data输出")}
但是层级非常多的时候代码就会变得非常繁琐且缺乏可读性,如下
obj={username:"花花",data:{age:18,height:170,weight:90,unit:{weight:"kg",height:"cm",data:{a:"最深层级参数1",b:"最深层级参数2"}}}}//通过判断正常输出if(obj.data&&obj.data.unit&&obj.data.unit.data){console.log(obj.data.unit.data.a)}
嵌套层级越多,上面的判断将变得越发的变态,所以接下来我们要讲讲可选链的使用了。
解决方案 - 可选链
上面我们说到可选链?.
属于一种安全的访问对象属性的方式,即使在在嵌套对象中出现不存在的属性也不会出现错误。如果可选链 ?.
前面部分是 undefined
或者 null
或者 空字符串
,那么它就会停止运算并返回undefined
。
通俗点讲就是:要正常访问嵌套对象属性,只要在可能会为空的属性后面加上可选链 ?.
那遇到空值就不会继续往后取值,并返回为空的属性值,下面我们通过几个案例来验证
obj={username:"花花",data:null,//data:{//age:18,//}}//验证data为空console.log("输出:"+obj.data?.age)
当层级会非常深时,这时可选链的可读性就展现出来了
obj={username:"花花",data:{age:18,height:170,weight:90,unit:{weight:"kg",height:"cm",data:{a:"最深层级参数1",b:"最深层级参数2"}}}}//可选链console.log("可选链:"+obj.data?.unit?.data?.a)//正常输出console.log("条件判断:"+obj.data.unit.data.a)
而当出现错误时,比如obj.data = null
,就会出现如下输出
obj.data=null//可选链console.log("可选链:"+obj.data?.unit?.data?.a)//正常输出console.log("条件判断:"+obj.data.unit.data.a)
除了取值之外还能安全的操作删除值,比如下面这段代码
//obj={//name:123//}obj=nullconsole.log(deleteobj?.name)console.log(deleteobj.name)
注意事项
我们知道可选链
?.
是对前一个值生效,成为可选值,但是这个值必须是已声明的值,否则则会报错
可选链扩展 ?.() , ?.[]
可选链属于一种特殊的运算符,它还能与函数和方括号一起使用
与函数使用:
varobj={test(){return"test函数被调用"}}//与函数一起使用,存在则调用函数,不存在则返回undefinedconsole.log(obj.test?.())console.log(obj.test2?.())
与方括号使用:
varobj={data:{username:"小花"}}varitem1='username'varitem2='name'console.log(obj.data?.[item1])console.log(obj.data?.[item2])
总结
可选链?.
一共有三种语法,主要用来检查左边部分是否为null/undefined/空字符串
,如果不是则继续运算。这样能让我们更加安全的访问嵌套对象属性。
obj?.prop
obj存在则返回obj.prop
的值,否则返回undefined
obj?.[prop]
obj存在则返回obj[prop]
的值,否则返回undefined
obj.method?.()
obj存在则调用obj.method
方法,否则返回undefined