什么是可選鏈
可選鏈操作符( ?. )是一個新的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];
規范