可选链操作符(Optional chaining operator):?.
你在学习或工作中肯定写过类似这样的代码:
if(user.score.english>=90){
console.log('及格')
}
看似好像没什么问题,确实,如果user对象像下面这样,确实不会有问题:
const user = {
username:'谢说前端',
score:{
chinese:120,
math:140,
english:110
}
}
但你有没有想过,如果user.score属性不存在,或者这个数据是ajax请求回来的,在数据没回来之前就进行判断,就会抛出如下错误
以前你可能会这么解决:
if(user.score && user.score.english>=90){
console.log('及格')
}
使用可选链操作符改造一下:
if(user.score?.english){
console.log('及格')
}
是不是很爽?
官方解释:
可选链操作符 是ES2020(ES10)推出的新特性,允许读取位于连接对象链深处的属性的值,而不必明确验证链中的每个引用是否有效。?.与.链式操作符不同之处在于,在引用为空(null或undefined) 的情况下不会引起错误,该表达式短路返回值是undefined
可选链操作符语法
可用在对象、数组、函数调用等语法中
obj?.propobj?.[expr]arr?.[index]func?.(args)
user?.score
user?.['score']
user.hobby?.[2]
user.show?.()
浏览兼容性
实际中的案例
以下为某同学在写Vue项目时经常犯的错(为了更容易理解,我简化了代码)
<template>
<div>
<p>用户名:{{user.username}}</p>
<p>英语成绩:{{user.score.english}}</p>
</div>
</template>
<script>
export default {
data(){
return {
user:{}
}
},
created(){
this.getUserInfo().then((data)=>{
this.user = data.data
})
}
//... 省略部分代码
}
</script>
最终的效果是效果能出来,但控制台会报一个错误,很初学者一直搞不懂,明明效果出来了,为什么还扬子报错?
其实是因为刚开始渲染视图时由于
user是一个空对象,对象中并没有score属性,user.score得到undefined,自然就不能继续user.score.english了,所以才报错,后面数据回来后成功渲染到页面
解决报错问题,以前你可以会这么做:
<p>英语成绩:{{user.score && user.score.english}}</p>
是不是很麻烦?什么?不麻烦?那你来写(如果你还是觉得不麻烦就当我没说......)
<p>英语成绩:{{user.score && user.score.english}}</p>
<p>数学成绩:{{user.score && user.score.math}}</p>
<p>语文成绩:{{user.score && user.score.chinese}}</p>
有了可选链操作符,你可以这么写:
<p>英语成绩:{{user.score?.english}}</p>
当数据没有请求回来时该表达式短路得到undefined,Vue会忽略掉null和undefined的值,故一开始不显示也不报错,直到数据返回后显示
空值合并操作符(Nullish coalescing operator):??
以前我们用得比较多的应用是逻辑与&&和逻辑或||,用于短路赋值操作。
我想从本地存储中拿到用户信息,但本地存储中user可能不存在,也有可能是空字符串,我的需求如下:
- 当本地存储不存在
user时赋值一个空对象 - 当
user有值时(哪怕是空字符串)也要保持这个值
一般我们写代码会这样写:
let user = localStorage.getItem('user') || {}
try{
user = JSON.parse(user)
}catch{
}
但上面代码其实会有一个问题,如果localStoreage.getItem('user')得到的是一个空字符串,还是会赋值空对象,用??就不会有问题,因为它只判断null和undefined的情况,而当本地存储中不存在user时得到的刚好是null,so
let user = localStorage.getItem('user') ?? {}
try{
user = JSON.parse(user)
}catch{
}
ok,完美实现上面需求
官方解释:
空值合并操作符(??)是一个逻辑操作符,当左侧的操作数为null或undefined时,返回其右侧操作数,否则返回左侧操作数
浏览器兼容性
操作符对比
left || right: 如果left为Truthy,则返回left否则返回rightleft && right: 如果left为Truthy,则返回right否则返回leftleft ?? right: 如果left为null或undefined,则返回right否则返回left
Truthy:真值,即转成Boolean类型为true的值Falsy:假值,即转成Boolean类型为false的值
来一波代码理解以上操作符:
const result = 0 || 'ok'; // 'ok'
const result = 1 || 'ok'; // 1
const result = null || 'ok'; // 'ok'
const result = true || 'ok'; // true
const result = 0 && 'ok'; // 0
const result = 1 && 'ok'; // 'ok'
const result = null && 'ok'; // null
const result = true && 'ok'; // 'ok'
const result = 0 ?? 'ok';// 0
const result = 1 ?? 'ok';// 1
const result = null ?? 'ok';// 'ok'
const result = true ?? 'ok'; // true
如果只是做赋值操作,其实还有一个更合适的操作符: 逻辑空赋值:??=,接着往下看
逻辑空赋值(Logical nullish assignment):??=
逻辑空赋值??=顾名思义就是用来赋值的,传统的=是直接赋值,而??=根据条件赋值(当左边的变量值为Nullish时才赋值),条件判断与??一至(当左边为null或undefined时才符合条件)
Nullish: 空值,即null或undefined
仍然是通过一波代码了解它的用法:
let pos = {x:10}
pos.x ??= 20; // pos.x不为null或undefined,故不赋值,所以pos.x仍然保持10
pos.y ??= 50; // pos.y为undefined,所以赋值50为pos.y
浏览器兼容性
很多小伙伴可能要说,什么,IE又不支持?
都什么年代了还抓着IE不放,大清已经灭亡,我们要住前看!
虽说有些可能还没成为正式的标准,但主流的浏览器已经完美支持,
退一万步来说,我们不是还有强大的babel么?怕啥
结语
好了,以上就是本篇文章所有内容,主要让大家了解三个新的操作符,学会后可以在很多时候简化我们的代码操作,大家也看到,随着ECMAScript版本不断升级,会有越来越多的好玩的新特性,请继续关注我,带你了解更多的前端知识