ES2020(ES11)新增了链判断运算符(?.)和Null 判断运算符(??),这两个运算符简化了项目中的代码,所以记录下来。先简单介绍一下,之后有深入的用法,再来补充。
1、链判断运算符(?.)
如果要获取对象中某一个属性,需要先判断一下这个对象是否存在,如果对象嵌套层数比较深,要一层一层的属性去判断,代码量就会很大。链判断运算符(?.) 解决了这个痛点。
// 动物
let animal = {
// 哺乳动物
mammal:{
// 兽类动物
beasts:{
// 老虎
tiger: {
location: 'china', // 归属地
count: 5, // 数量
isAdult: true // 是否成年
}
}
}
}
我们要获取最里面老虎的归属地,需要一层层判断。
let tigerLocation = (animal
&& animal.mammal
&& animal.mammal.beasts
&& animal.mammal.beasts.tiger
&& animal.mammal.beasts.tiger.location) || 'default';
如果嵌套层数比较深的话,代码量会很多,链判断运算符(?.) 就帮我们解决了这个难题,请看:
let tigerName = animal?.mammal?.beasts?.tiger?.location || 'default'
是不是简化了很多。
当然还有好多其他的用法:
let box1 = document.getElementById('box1');
// 先判断box1是否存在
box1?.addEventListener('click',function(){
alert("检查空值");
})
2、Null 判断运算符(??)
读取某个值或者对象属性的时候,有可能这个值是null或者undefined,所以通常会设置一个默认值。
let tigerLocation = animal.mammal.beasts.tiger.location || ‘china’;
let tigerCount = animal.mammal.beasts.tiger.count|| 10;
let tigerisAdult = animal.mammal.beasts.tiger.isAdult|| true;
上面三行代码都通过或运算符指定默认值,但是这样写是错的。开发者的原意是,只要属性的值为null或undefined,默认值就会生效,但是属性的值如果为空字符串或false或0,默认值也会生效。
为了避免这种情况,ES2020 引入了一个新的 Null 判断运算符??。它的行为类似或运算符,但是只有运算符左侧的值为null或undefined时,才会返回右侧的值。 默认值只有在属性值为null或undefined时,才会生效。
这个运算符的一个目的,就是跟链判断运算符?.配合使用,为null或undefined的值设置默认值。
let tigerLocation = animal?.mammal?.beasts?.tiger?.location ?? ‘china’;
let tigerCount = animal?.mammal?.beasts?.tiger?.count ?? 10;
let tigerisAdult = animal?.mammal?.beasts?.tiger?.isAdult ?? true;
上面代码中,如果属性值是null或undefined,就会返回默认值。
Null 判断运算符(??)有一个运算优先级问题,需要注意,它与&&和||的优先级孰高孰低。现在的规则是,如果多个逻辑运算符一起使用,必须用括号表明优先级,否则会报错。
// 报错
animal && beasts ?? tiger
animal ?? beasts && tiger
animal || beasts ?? tiger
animal ?? beasts || tiger
上面四个表达式都会报错,必须加入表明优先级的括号。
(animal && beasts ) ?? tiger;
animal && (beasts ?? tiger);
(animal ?? beasts ) && tiger;
animal ?? (beasts && tiger);
(animal || beasts ) ?? tiger;
animal || (beasts ?? tiger);
(animal ?? beasts ) || tiger;
animal ?? (beasts || tiger);
感谢这篇文章的帮助:ES6–09 对象的简洁写法、扩展运算符和判断运算符