概念
可选链运算符(?.)允许读取位于连接对象链深处的属性的值(嵌套对象结构),而不必明确验证链中的每个引用是否有效。?. 运算符的功能类似于 . 链式运算符,不同之处在于,在引用为空( null 或者 undefined ) 的情况下不会引起错误,该表达式短路返回值是 undefined。与函数调用一起使用时,如果给定的函数不存在,则返回 undefined。
白话解析
面试题:访问一个对象中未存在的属性成员时,其返回值是什么?
:
:
答案:undefined
当我们在开发中,访问一个 未知对象 或者 拥有动态成员对象 的时候,你不能保证你访问当前对象的 某个属性 或者 某个方法 的存在性(有效性)。那么 结果可能出现上面引入的面试图场景,访问了一个不存在的属性,你将会得到一个undefined。
代码验证
A段
let obj = {
w1:'小雨',
w2:'晴天',
w3:'暴雨',
wP:function(){
console.log(obj.w1)
}
}
使用A段代码验证:访问对象obj中没有的成员w4时,返回undefined。
铺垫到这,有人会问,与可选链运算符(?.) 有什么关系呢?上面返回undefined值,是因为访问了 对象中不存在的值,是对象的访问机制。那么你肯定也遇到多层对象嵌套的数据结构吧?如下面B段代码,如果多层链路调用访问内部深层对象的值时,当中间层对象不存在时,会出现什么结果呢?
B段
let obj2 = {
objSun:{
test:'测试'
}
}
例如上图,当我们知道中间层对象objSun存在的情况下,再访问最终的test值,一切都是那么顺利。
但是如果objSun 的 存在性 是 未知的。上图以objSun2 不存在的中间层对象 模拟假如objSun不存在时,再访问其内部深层值,就会出现报错。
这里的中间层的对象 不存在的情况 并不是我为了模拟而模拟这样的,因为在实际开发中,你必然会遇到这样的问题。下面简要说明 出现场景。
问题场景描述
在使用一些接口返回的数据时,难免会有 对象包裹对象的数据形式,这种嵌套也可能是多层。后台接口返回数据的过程,都有一定的不确定性,比如出现,参数,网络,或者服务器问题等,当我们拿不到本该是正确数据形式的数据 的时候。那么在正常情况下使用这些 多嵌套深层数据的地方,就可能出现如上图 这种类似的报错。其报错原因是,访问了未知未定义数据的成员。
- 那么 如何避免 这种问题的出现?就得让 在进行访问深层嵌套对象数据时的程序,确保 每一层级对象 的存在性。
- 如何确保?
技术细节
- 传统方法
let objUser= obj.objSun&& obj.objSun.test;
通过 逻辑运算符 的短路特性,为了避免报错,在访问obj.first.second之前,要保证 obj.first 的值既不是 null,也不是 undefined
。如果只是直接访问 obj.objSun.test,而不对 obj.first 进行校验,则有可能抛出错误。
- JavaScript可选链运算符(?.)
let objUser= obj.objSun?.test;
通过使用 ?. 运算符取代 . 运算符,JavaScript 会在尝试访问 obj.first.second 之前,先隐式地检查并确定 obj.first 既不是 null 也不是 undefined。如果obj.objSun 是 null 或者 undefined,表达式将会短路计算直接返回 undefined。
上述:两种方法 原理一样,但是 可选链运算符(?.) 在使用时,代码会跟简洁。
小结
1.为什么要使用 JavaScript可选链运算符(?.)?
1.代码层面:更严谨的同时,代码较为简洁。
2.逻辑层面:代码的执行,undefined 和 报错 是两个不同的结果。报错会直接影响代码整体的运行;而 undefined 我们可以通过严谨的过滤方法,去把出现undefined的情况考虑在内。动态处理问题,让代码的健壮性更强大。
相关文章
MDN: 可选链运算符(?.)