javascript Optional chaining:可选链操作符(?.)的介绍与使用
例:有如下对象
let person = {
name: 'pyq',
age: 18,
address: {
// country: 'CHINA',
// city: {
// city: 'shengzhen',
// area: 'nanshan'
},
},
getInfo: function() {
return `${this.name}今年${this.age}岁了,家住${this.address.country}${this.address.city.city}`
}
}
当我们访问person.adress.country时,程序报出如下错误
// Uncaught TypeError: Cannot read property code of undefined
一般情况下,思考一个存在嵌套结构的对象 obj,查找一个深度嵌套的子属性时,需要验证之间的引用,例如:
let area = obj.address ? obj.address.city ? obj.address.city.area
let area = ((obj || {}).address || {}).city || {}).area
try {
const area = obj.address.city.area
} catch(e) {
}
可选链调用
有了可选链操作符(?.),在访问 obj.first.second 之前,不再需要明确地校验 obj.first 的状态,再并用短路计算获取最终结果:
let area = obj?.address?.city?.area
通过使用(?.)操作符代替(.)操作符,javascript会尝试在访问address之前先隐式的检查并确定obj不为null也不为undefined,如果结果为null或者undefined,表达式会短路计算直接返回undefined
这等价于以下表达式,但不创建临时变量:
let temp = obj.address
let areaTemp = (temp !== null && temp !== undefined) ?
(temp.city !== null && temp !== undefined) ?
temp.city.area : undefined : undefined
函数调用
当尝试调用一个可能不存在的方法时也可以使用可选链。使用可选链可以使表达式自动返回undefined而不是抛出一个异常。
person.getInfo?.()
person.getAge?.() //可调用不存在的函数
person.name?.() // 如果存在一个属性名且不是函数,js仍然会抛出一个错误TypeError 异常 (x.y is not a function).
user?.getUser?.() // 如果要允许调用调用函数存在的对象也为null或者undefined,则要在对象后也加(?.)
处理可选的回调函数或者事件处理器
1.
.then(res) => {
if (res && res.code === 200) {
return res.data || {}
}
}
可改写为
.then(res) => {
return res?.code === 200 ? res.data : {}
}
2.
function(OnContent, OnError) {
try {
} catch(err) {
if(OnError) {
OnError(err)
}
}
}
可改为
function(OnContent, OnError) {
try {
} catch(err) {
OnError?.(err)
}
}
使用中括号表达式引用动态属性
let prop = name
let result = person?.[prop]
访问数组元素
let arr = [1,2,3,4,5,7]
arr?.[0]
使用空值合并操作符(??)
空值合并操作符(??)是一个逻辑操作符,当左侧的操作数为 null 或者 undefined 时,返回其右侧操作数,否则返回左侧操作数。
person.sex = person?.sex ?? '人妖'
不能直接在可选链上进行赋值
let object = {};
object?.property = 1; // Uncaught SyntaxError: Invalid left-hand side in assignment