1. 程式人生 > 其它 >JS 特性:可選鏈(?.)

JS 特性:可選鏈(?.)

什麼是可選鏈

可選鏈操作符( ?. )是一個新的js api,允許讀取位於連線物件鏈深處的屬性的值,而不必明確驗證鏈中的每個引用是否有效。?. 操作符的功能類似於 . 鏈式操作符,不同之處在於,在引用為空(nullish ) (null 或者 undefined) 的情況下不會引起錯誤,該表示式短路返回值是 undefined。與函式呼叫一起使用時,如果給定的函式不存在,則返回 undefined。
語法:

obj?.prop
obj?.[expr]
func?.(args)

上述是官方描述,舉個例子物件嵌套了好多層,需要獲得物件深層的值得時候,這就意味著你需要寫很長的屬性訪問,如下:

const
person = { details: { name: { newName: "aa", oldName: "aa", } age: "18", }, jobs: [ "H5", "Java" ] } const personNewName = person.details.name.newName;

上面的程式碼如果我的person.details.name等任何一層資料有問題或者不存在的時候,js就會報錯,我們一般會這麼改進:

 const personNewName =  person && person.details && person.details.name person.details.name.newName|| '';

可以看到為了訪問某個人的 newName,程式碼變得非常不優雅,會有多個&&程式碼量也很大。可選鏈 就是為了解決這個問題而誕生的。

用法

有了可選鏈操作符(?.),在訪問 person.details.name.newName 之前,不再需要明確地校驗 person.details.name 的狀態,再並用短路計算獲取最終結果:

const
personFirstName = person?.details?.name?.firstName;

其實就是在屬性訪問符 . 的前面加了個問號。我們看上面語句中第一個 ?. ,從 JS 層面,它表示如果 person 的值為 null 或者 undefined,就不會報錯而返回 undefined,否則才繼續訪問後面的 details 屬性。而如果後面的屬性訪問鏈中有任何一個屬性為 null 或者 undefined,那麼最終的值就為 undefined。
這等價於以下表達式,但實際上沒有建立臨時變數:

let temp = person.details;
let nestedProp = ((temp === null || temp === undefined) ? undefined : temp.name);
let temp1 = person.details.name;
let nestedProp = ((temp1 === null || temp1 === undefined) ? undefined : temp1.firstName);

可選鏈與函式呼叫

函式呼叫時如果被呼叫的方法不存在,使用可選鏈可以使表示式自動返回undefined而不是丟擲一個異常。

let result = someInterface.customMethod?.();

注意: 如果存在一個屬性名且不是函式, 使用 ?. 仍然會產生一個 TypeError 異常 (x.y is not a function).
注意: 如果 someInterface 自身是 null 或者 undefined ,異常 TypeError 仍會被丟擲 someInterface is null 如果你希望允許 someInterface 也為 null 或者 undefined ,那麼你需要像這樣寫 someInterface?.customMethod?.()

可選鏈和表示式當使用方括號與屬性名的形式來訪問屬性時,你也可以使用可選鏈操作符:

let nestedProp = obj?.['prop' + 'Name'];

可選鏈不能用於賦值

let object = {};
object?.property = 1; // Uncaught SyntaxError: Invalid left-hand side in assignment

可選鏈訪問陣列元素

let arrayItem = arr?.[42];

規範