ES6+ 可選鏈操作符
1. 前言
在 ES5 中對于安全地訪問對象的深嵌套屬性時(shí),首先檢查它的上一個(gè)屬性是否存在,然后才能獲取屬性的值,否則就會(huì)報(bào)錯(cuò):
var obj = {}
console.log(obj.a) // undefined
console.log(obj.a.b) // Uncaught TypeError: Cannot read property 'b' of undefined
上面的代碼中,obj 是一個(gè)對象,在獲取 obj 對象的屬性 a 時(shí),屬性 a 沒有被定義所以返回 undefined,第 3 行獲取 obj 對象 a 下的 b,由于 obj 上沒有 a 屬性,再獲取 a 上的 b 屬性就會(huì)報(bào)錯(cuò)。一般這樣的情況,在程序中需要做前置驗(yàn)證,大部分情況會(huì)借助 &&
來完成。
var obj = {}
var b = obj.a && obj.a.b
console.log(b) // undefined
上面的代碼中第 2 行首先會(huì)判斷 obj.a
的值,如果不為空則繼續(xù)執(zhí)行 obj.a.b
否則返回 undefined
。這樣做雖然能保證程序的健壯性,但當(dāng)嵌套的對象很深時(shí),則要對每一層進(jìn)行驗(yàn)證,這樣不利于閱讀,而且容易出現(xiàn)程序上的錯(cuò)誤。
針對上面的場景,ES2020 最新的版本給出了它的解決方案 —— 可選鏈操作符。我們可以直接在瀏覽器的控制臺(tái)中進(jìn)行測試,那什么是可選鏈操作符呢?本節(jié)我們來學(xué)習(xí)這個(gè) ES6 的新語法。
2. 方法詳情
可選鏈操作符使用 ?.
來表示,可以判斷操作符之前屬性是否有效,從而鏈?zhǔn)阶x取對象的屬性或返回 undefined
。
作用與 .
操作符類似。不同的是 ?.
如果對象鏈上的引用是 null
或者 undefined
時(shí), .
操作符會(huì)像前言中的例子拋出一個(gè)錯(cuò)誤,而 ?.
操作符則會(huì)按照短路計(jì)算的方式進(jìn)行處理,返回 undefined
??蛇x鏈操作符也可用于函數(shù)調(diào)用,如果操作符前的函數(shù)不存在,也將會(huì)返回 undefined
。下面我們來看它的使用語法:
2.1 基本語法
語法使用:
obj?.prop
obj?.[expr]
arr?.[index]
func?.(args)
參數(shù)解釋:
參數(shù) | 描述 |
---|---|
prop | 對象上的屬性 |
expr | 對象上的屬性可以是一個(gè)表達(dá)式 |
index | 對數(shù)組使用時(shí),可以接數(shù)組的位置 |
args | 對函數(shù)使用時(shí),可以接收傳入的參數(shù) |
實(shí)例
var user = {
name: 'Kira',
address: {
city: 'beijing',
other: {}
}
}
console.log(user?.name); // Kira
a?.b); // undefined
console.log(user?.address?.city); // beijing
console.log(user?.address?.other?.a?.b); // undefined
上面的代碼可以看出,使用的方式很簡單,在確保上一個(gè)值是有效時(shí)才會(huì)去獲取下面的屬性,避免程序報(bào)錯(cuò)。
對象的引用或函數(shù)可能是 undefined
或 null
時(shí),可選鏈操作符提供了一種方法來簡化被連接對象的值訪問。
3. 使用場景
3.1 可選鏈和表達(dá)式
當(dāng)使用方括號(hào)與屬性名的形式來訪問屬性時(shí),你也可以使用可選鏈操作符:
let firstName = obj?.['first' + 'Name'];
3.2 可選鏈與函數(shù)調(diào)用
當(dāng)嘗試調(diào)用一個(gè)可能不存在的方法時(shí)也可以使用可選鏈。這將是很有幫助的。當(dāng)函數(shù)調(diào)用時(shí)如果被調(diào)用的方法不存在,使用可選鏈可以使表達(dá)式自動(dòng)返回 undefined
而不是拋出一個(gè)異常。
var person = {}
var name = person.getName?.();
注意:如果屬性名不是函數(shù)也會(huì)報(bào)錯(cuò),可選鏈只會(huì)判斷屬性是否有效,而不能判斷屬性的類型。
var person = {getName: ''}
var name = person.getName?.();
// Uncaught TypeError: person.getName is not a function
3.3 可選鏈不能用于賦值
可選鏈?zhǔn)侨≈挡僮鲿r(shí)所用的安全方法,不能使用在賦值操作上。
let obj = {};
obj?.name = 'imooc'; // Uncaught SyntaxError: Invalid left-hand side in assignment
上面的代碼第 2 行使用可選鏈進(jìn)行賦值操作,控制臺(tái)會(huì)報(bào)語法錯(cuò)誤,賦值的左側(cè)是無效的。
3.4 可選鏈訪問數(shù)組元素
可選鏈也是可以使用在數(shù)組取值的前置驗(yàn)證的。
var arr = []
let item = arr?.[5];
4. 小結(jié)
本節(jié)學(xué)習(xí)了 ES6 中新增的可選鏈語法,它提供了一種方法來簡化被連接對象的值訪問,保證訪問數(shù)據(jù)的安全性。它可以用于對象、數(shù)組、函數(shù)中。這個(gè)語法很有用,在項(xiàng)目中使用可以達(dá)到事半功倍的效果。