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 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 對象的簡潔寫法、擴充運算符和判斷運算符