欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

javascript Optional chaining:可选链操作符(?.)的介绍与使用

程序员文章站 2022-06-06 23:42:45
...

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