ES2020新特性鏈操作符 '?.'和'??'

帥鍋、宇發表於2021-12-01

ES2020新特性,js中的可選鏈操作符?.

概述

回想一下,我們是如何訪問可能含有空值(null或undefined)屬性的巢狀物件,比如訪問web api 返回結果的user詳情,可以使用巢狀的三元運算子像這樣:

const userName = response ? (response.data ? (response.data.user ? response.data.user.name : null) : null) : null;

或者使用if語句進行空值檢查:

let userName = null;
if(response && response.data && response.data.user){
  userName = response.data.user.name;
}

或者寫的更好點:

const userName = response && response.data && response.data.user && response.data.user.name;

上面程式碼中的共同點是,程式碼有時會非常冗長,並且變得難以格式化和閱讀。這就是可選鏈操作符 ?. 救場的地方, 它提供隱式無效檢查使我們的程式碼更精煉更好。

const userName = response?.data?.user?.name;

語法

可選鏈操作符 ?. 是在 Javascript ES2020 中引入的,其語法如下:

obj.val?.prop       如果val存在返回 obj.val.prop, 否則 undefined.
obj.func?.(args)    如果func存在返回 obj.func(args) , 否則 undefined.
obj.arr?.[index]    如果array存在返回 obj.array[index] , 否則 undefined.

用法

以user物件為例,學習 ?. 的用法

const user = {
  name: "John",
  age: 21,
  homeaddress: {
    country: "USA"
  },
  hobbies: [{name: "Coding"}, {name: "Cooking"}],
  getFirstName: function(){
    return this.name;
  }
}
物件

訪問存在的屬性返回值:

console.log(user.homeaddress.country); 
// 列印 "USA";

訪問不存在的屬性會報錯:

console.log(user.officeaddress.country); 
// throws error "Uncaught TypeError: Cannot read property 'country' of undefined"

使用可選鏈操作符 ?. 訪問不存在的屬性。返回 undefined

console.log(user.officeaddress?.country); 
// 列印 "undefined"
方法

呼叫存在的方法:

console.log(user.getFirstName()); 
// 列印 "John";

呼叫不存在的方法會丟擲異常

console.log(user.getLastName()); 
// throws error "Uncaught TypeError: user.getLastName is not a function";

使用可選鏈操作符 ?. 訪問不存在的方法,返回 undefined

console.log(user.getLastName?.()); 
// prints "undefined"
陣列

訪問陣列存在的索引返回值:

console.log(user.hobbies[0].name); 
// 列印 "Coding";

訪問陣列不存在的索引丟擲異常:

console.log(user.hobbies[3].name); 
// throws error "Uncaught TypeError: Cannot read property 'name' of undefined"

使用可選鏈操作符 ?. 訪問陣列不存在的索引,返回 undefined

console.log(user.hobbies[3]?.name); 
// prints "undefined"

訪問不存在的陣列,會丟擲異常

console.log(user.dislikes[0].name); 
// throws error "Uncaught TypeError: Cannot read property '0' of undefined"

使用可選鏈操作符 ?. 訪問不存在的陣列,返回 undefined :

console.log(user.dislikes?.[0]?.name); 
// prints "undefined"
與空值合併操作符??一起使用

有的時候,我們希望不返回 undefined 而是返回一個預設值,這個時候,我們可以使用空值合併操作符??完成這一工作。

不使用 ?? ,返回 undefined :

const country = user.officeaddress?.country;
console.log(country);
// 列印 "undefined"

?? 合用,返回一個預設值

const country = user.officeaddress?.country ?? "China";
console.log(country);
// 列印 "China"

相關文章