前言
问:一个问号是什么意思?
答:跟冒号配合可以用作三元操作符。
问:还有么?
答:用在对象的取值判断上,那就是可选链;
问:两个问号呢?
答:双问号操作符。
问:多个问号呢?
答:那是杨少侠!
三元操作符
js里面问号的用处,可能第一个想到的就是三元操作符boolean ? trueValue : falseValue,这个是js的基础操作符。
isMrYoung ? 'yes' : 'no'
复制代码
三元操作符返回一个值,如果问号前面是真那就返回问号后面的值,否则返回冒号后面的值。不多赘述。
可选链
如果有一个user对象:
{
"name": "kaiser",
"hobby": {
"sports": {
"summer": "basketball",
"winter": "sleep"
}
}
}
复制代码
我们想获取玩家夏天最爱的运动,那就应该是user.hobby.sports.summer,问题来了,如果这个人没有爱好或者爱好里面没有运动,或者没有夏天喜欢的运动呢?问题不大,判断一波嘛。
if (user && user.hobby && user.hobby.sports && user.hobby.sports.summer) {
return user.hobby.sports.summer
}
复制代码
好像有点冗长, 这才三层,如果更深的层级就更加刺激了,不对,再来!
try {
return user.hobby.sports.summer
} catch(e) {
return undefined
}
复制代码
这样能一劳永逸解决任何长度的层级,但是还不够优雅。不对,再来!
import get from 'lodash/get'
const result = get(user, 'hobby.sports.summer')
复制代码
只要任何一个环节出现问题,都会返回一个undefined
,但是这需要使用第三方库,不够优雅。不对,再来!
祭出杀手锏,可选链:
return user?.hobby?.sports?.summer
复制代码
上面的例子,如果其中一个属性是null
或者undefined
,不会报错,而是会返回undefined
,比如查询的user对象是下面三种情况:
{
"hobby": {}
}
{
"hobby": null
}
{
"hobby": {
"sports": "basketball"
}
}
复制代码
那么得到的返回值都是undefined
。
可选链还有多种写法:
obj?.prop // 对象的点号判断 user?.hobby?.sports
obj?.[expr] // 对象的方括号判断 user?.['hobby']?.['sport']
arr?.[index] // 数组判断 userList?.[12]?.name
func?.(args) // 方法判断 user?.run?.('1hours')
复制代码
看看兼容性:
如果你使用了bable来编译你的代码,那就放心用吧。@babel/plugin-proposal-optional-chaining
双问号操作符
如果要给一个变量A赋值为变量B,但是如果B没有值的时候,我们希望A有一个默认值,我们可能这样写:
const a = b || 'defaultVale'
复制代码
问题来了,如果b是一个数字0或者false
, 那就得不到想要的结果了,a就变成了’defaultValue’,而此时你想要的可能就是这个0或者false
可以用双问号操作符解决这个问题:
const a = b ?? 'defaultValue'
复制代码
只有当a是undefined 或者 null的时候,才会给a赋默认值’defaultValue’,否则都会得到b的值。
cosnt b = 0
const a = b ?? 'default' // a === 0
const b = false
cosnt a = b ?? 'default' // a === false
复制代码
NICE~
不知道三个问号写法放在一起,有没有搞头:
const result = a?.b ?? true ? 'd' : 'f'
复制代码
总结
为了让你的JS更加优雅,赶紧用起来吧。当然不要为了炫技,搞很复杂的组合写法,不然到时候一脸问号的可能就是你的同事了。
下一篇文章:《Vue3 – setup script超爽体验,你值得一试》