自我学习总结:
链判断运算符(?. )
?.运算符,直接在链式调用的时候判断。 左侧的对象是否为null或undefined。 如果是的,就不再往下运算,而是返回undefined 本质上,?.运算符相当于一种短路机制,只要不满足条件,就不再往下执行。
如果读取对象内部的某个属性,往往需要判断一下。
属性的上层对象是否存在。比如,读取 message.body.user.firstName这个属性,安全的写法是写成下面这样。
let message={
body:{
user:{
firstName:''
}
}
}
// 错误的写法;因为这message.body这个值可能没有,会导致报错
const firstName = message.body.user.firstName || 'default';
// 正确的写法
const firstName = (message
&& message.body
&& message.body.user
&& message.body.user.firstName) || 'default';
有的小伙伴可能会觉得这样会很麻烦,怎么会处理这个问题了。
//使用链式运算符
let myDefault= message?.body?.user?.firstName || '默认值';
/**
* 上面代码中,如果message是null或undefined,
* 或者message.body是null或undefined,
* 或者message.body.user是null或undefined,
* 或者message.body.user.firstName是null或undefined.
* 就会返回--默认值。
* */
用途有三:
- 判断对象是否有某个方法:func?.(...args)
- 判断对象属性:obj?.prop
- 判断是否有某个变量:obj?.[expr]
?.运算符常见形式
let hex = "#C0FFEE".match(/#([A-Z]+)/i)?.[1];
a?.b
// 等同于
a == null ? undefined : a.b
a?.[x]
// 等同于
a == null ? undefined : a[x]
a?.b()
// 等同于
a == null ? undefined : a.b()
a?.()
// 等同于
a == null ? undefined : a()
// say:function(){
// console.log('hello word')
// }
}
//如果没有该方法,则不会被执行的哈
message.say?.()
//返回undefined
console.log(message.say?.())
使用的注意事项:
- 短路机制:
?.运算符相当于一种短路机制,只要不满足条件,就不再往下执行 若是左侧是undefined或null,则右侧默认不在执行 - delete运算符:
如果
a是undefined或null,会直接返回undefined,而不会进行delete运算
// 等同于
a == null ? undefined : delete a.b
- 括号的影响 如果属性链有圆括号,链判断运算符对圆括号外部没有影响,只对圆括号内部有影响 如下所示:不管a对象是否存在,圆括号后面的.c都是会执行的,一般不会使用圆括号
// 等价于
(a == null ? undefined : a.b).c
- 报错场合:下面的写法是错误的
new a?.()
new a?.b()
// 链判断运算符的右侧有模板字符串
a?.`{b}`
a?.b`{c}`
// 链判断运算符的左侧是 super
super?.()
super?.foo
// 链运算符用于赋值运算符左侧
a?.b = c
- 右侧不得为十进制数值 ?.若跟着一个十进制的数字,那么?.不在被看做是一个完整的运算符,会按照三元运算符处理
Null判断运算符:??
读取对象属性的时候,若是属性的值是null或undefined,需要给他们制定默认值,常见做法是用||,但是若是属性值为空字符串或者false或者0,默认值也会生效,因此ES2022引入??,行为类似||,但只有左侧是null或者undefined,才会返回右侧的值
配合链判断符号一起使用,为null或者undefined设置默认值 如下:如果response.settings是null或undefined,或者response.settings.animationDuration是null或undefined,就会返回默认值300。也就是说,这一行代码包括了两级属性的判断。(阮老师已修正)
const animationDuration = response.settings?.animationDuration ?? 300;