JavaScript?新提案optional?chaining可選鏈屬性原理詳解
Optional chaining
這是一項(xiàng)新的提案,老舊瀏覽器可能需要 polyfills。
Optional chaining ?.(可選鏈,以下簡(jiǎn)稱 OC)是一種以安全的方式去訪問嵌套的對(duì)象屬性,即使某個(gè)屬性根本就不存在。
起因:
一個(gè)在 JavaScript 中很常見的問題就是:假如用戶信息中,地址是可填可不填的,那我們就無法安全地訪問地址的某一個(gè)屬性:
let user = {}; // 用戶可能沒有填地址
alert(user.address.street); // 報(bào)錯(cuò)或者下面這種情況,在 WEB 開發(fā)中,我們可能需要去獲取一個(gè) DOM 元素,但是這個(gè) DOM 元素可能不存在:
// 當(dāng) querySelector(...) 的結(jié)果為 null 的時(shí)候,程序會(huì)報(bào)錯(cuò)
let html = document.querySelector('.my-element').innerHTML;在 OC ?. 出現(xiàn)之前,我們一般通過邏輯與操作來解決:
let user = {}; // 沒有地址的用戶
alert( user && user.address && user.address.street ); // undefined (不會(huì)報(bào)錯(cuò))使用邏輯與操作符可以確保表達(dá)式的所有部分都能夠正確執(zhí)行,但是寫法卻比較笨重。
Optional chaining(可選鏈)
OC ?. 能夠使代碼變得簡(jiǎn)便,當(dāng)位于其前的值為 undefined 或者是 null 時(shí),會(huì)立即阻止代碼的執(zhí)行,并且返回 undefined。
通過 OC,我們可以安全地訪問用戶的地址:
let user = {}; // 一個(gè)沒有地址的用戶
alert( user?.address?.street ); // undefined (不會(huì)報(bào)錯(cuò))即使 user 對(duì)象不存在,使用 OC 訪問它的地址屬性也不會(huì)報(bào)錯(cuò):
let user = null; alert( user?.address ); // undefined alert( user?.address.street ); // undefined
需要注意的是,OC 僅允許它前面相鄰的部分為可選項(xiàng),不包括進(jìn)一步的值。
在上面的代碼中,user?. 僅允許 user 這個(gè)對(duì)象為 null 或 undefined 。
另一方面,如果 user 這個(gè)對(duì)象真的存在,那么 user.address 這個(gè)屬性必須存在,否則訪問 user?.address.street 則會(huì)在第二個(gè)點(diǎn)這報(bào)錯(cuò)。
不要過度使用 OC
我們應(yīng)該僅在希望某個(gè)值可能不存在的情況下才使用 ?.例如,根據(jù)我們的代碼邏輯,user 對(duì)象必須存在,但是 address 屬性是可選的,所以 user.address?.street 才是更好的選擇。
所以,由于其他原因?qū)е碌?nbsp;user 對(duì)象為 undefined 的情況才能被快速發(fā)現(xiàn)。否則,bug 將會(huì)變得比較難找
位于 ?. 前的變量必須被顯示聲明
如果 user 這個(gè)變量根本沒有被聲明,那么 user?.anything 將會(huì)觸發(fā)一個(gè)錯(cuò)誤:
// ReferenceError: user is not defined user?.address;
此處必須有變量聲明語句 let/const/var, OC 對(duì)未聲明的變量無效
短路
在上文提到,在OC ?. 的前部分的值為 null 或 undefined 的時(shí)候,會(huì)立即停止執(zhí)行。
所以,如果在其后面如果有函數(shù)的調(diào)用,或者其他操作,都不會(huì)執(zhí)行。
let user = null; let x = 0; user?.sayHi(x++); // 什么都不會(huì)做 alert(x); // 0,值沒有自增
其他用法:?.(),?.[]
OC 不是一個(gè)操作符,而是一個(gè)特別的語法糖,所以可以和函數(shù)調(diào)用和中括號(hào)共用。
例如,?.()可以用于執(zhí)行一個(gè)可能不存在的函數(shù)。
下面的代碼中,一些用戶擁有 admin 方法,一些用戶沒有:
let user1 = {
admin() {
alert("I am admin");
}
};
let user2 = {};
user1.admin?.(); // I am admin
user2.admin?.();我們首先用點(diǎn)語法去獲取 admin 方法,因?yàn)?user 對(duì)象肯定存在,所以我們可以安全地去訪問;
然后使用 ?.() 檢查其左側(cè),如果 admin 這個(gè)方法存在,就執(zhí)行(例如 user1),否則就停止執(zhí)行,但是不報(bào)錯(cuò)(例如 user2)。
?.語法同樣可以在當(dāng)我們需要通過中括號(hào)去訪問屬性時(shí)使用,使用它可以安全的訪問一個(gè)或許還不存在的對(duì)象的屬性:
let user1 = {
firstName: "John"
};
let user2 = null; // 假如現(xiàn)在不能授權(quán)這個(gè)用戶
let key = "firstName";
alert( user1?.[key] ); // John
alert( user2?.[key] ); // undefined
alert( user1?.[key]?.something?.not?.existing ) // undefined?. 同樣可以與 delete操作符共用
delete user?.name; // 刪除用戶名,如果用戶存在的話
使用 ?. 可以進(jìn)行刪除和讀取操作,但是不能進(jìn)行賦值操作
在賦值運(yùn)算符的左側(cè),?. 無效
// 下面的代碼是假設(shè)現(xiàn)在需要在用戶存在的情況下,重新賦值 name 屬性 user?.name = "John"; // 報(bào)錯(cuò) // 等同于 undefined = "John"
總結(jié)
OC ?. 有三種形式:
obj?.prop- 如果obj存在的話,返回obj.prop的值,否則返回undefined;obj?.[prop]- 如果obj存在的話返回obj[prop]的值,否則返回undefined;obj?.method()- 如果obj存在的話則調(diào)用obj.method()方法,否則返回undefined。
這幾種形式都非常的直觀并且易于使用。?. 檢查左側(cè)的值是否為 null 或 undefine,如果不是的話則繼續(xù)執(zhí)行。
通過鏈?zhǔn)降?nbsp;?. 可以安全地訪問嵌套的對(duì)象。
我們應(yīng)該僅在當(dāng)左側(cè)的值可能不存在的情況下才使用 ?.,這樣在發(fā)生錯(cuò)誤的時(shí)候才能更加容易找到問題。
參考鏈接:
https://javascript.info/optio...
https://developer.mozilla.org...
https://tc39.es/ecma262/#prod...
以上就是JavaScript 新提案optional chaining可選鏈的詳細(xì)內(nèi)容,更多關(guān)于JavaScript可選鏈的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
javascript實(shí)現(xiàn)異形滾動(dòng)輪播
這篇文章主要為大家詳細(xì)介紹了javascript實(shí)現(xiàn)異形滾動(dòng)輪播,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2019-11-11
Bootstrap彈出框(modal)垂直居中的問題及解決方案詳解
這篇文章主要介紹了Bootstrap彈出框(modal)垂直居中的問題及解決方案詳解的相關(guān)資料,非常不錯(cuò)具有參考借鑒價(jià)值,需要的朋友可以參考下2016-06-06
JavaScript獲取服務(wù)器端時(shí)間的方法
這篇文章主要介紹了JavaScript獲取服務(wù)器端時(shí)間的方法,非常不錯(cuò),具有參考借鑒價(jià)值,需要的朋友可以參考下2016-11-11
javascript實(shí)現(xiàn)的一個(gè)帶下拉框功能的文本框
這篇文章主要介紹了javascript實(shí)現(xiàn)的一個(gè)帶下拉框功能的文本框,需要的朋友可以參考下2014-05-05
前端開發(fā)基礎(chǔ)javaScript的六大作用
這篇文章主要介紹了前端開發(fā)基礎(chǔ)javaScript的六大作用,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2020-08-08
JavaScript之Getters和Setters 平臺(tái)支持等詳細(xì)介紹
現(xiàn)在,JavaScript的Getters和Setters使用非常廣泛,它和每個(gè)JavaScript開發(fā)者的切身利益息息相關(guān),我們先來快速了解什么是Getters和Setters,以及它們?yōu)槭裁春苡杏?然后,我們來看看現(xiàn)在都有哪些平臺(tái)支持Gettets和Setters2012-12-12
微信小程序使用wx.navigateTo路由跳轉(zhuǎn)層級(jí)限制問題小結(jié)
在微信小程序開發(fā)中,wx.navigateTo和wx.redirectTo是兩種頁面跳轉(zhuǎn)方式,wx.navigateTo允許跳轉(zhuǎn)到新頁面并保留當(dāng)前頁面,適合需要返回的場(chǎng)景,但受頁面棧10層限制,wx.redirectTo則關(guān)閉當(dāng)前頁面后跳轉(zhuǎn),本文介紹微信小程序使用wx.navigateTo路由跳轉(zhuǎn)層級(jí)限制問題2024-10-10
詳解js中構(gòu)造流程圖的核心技術(shù)JsPlumb(2)
這篇文章主要介紹了js中構(gòu)造流程圖的核心技術(shù)JsPlumb,jsPlumb是一個(gè)強(qiáng)大的JavaScript連線庫,它可以將html中的元素用箭頭、曲線、直線等連接起來,適用于開發(fā)Web上的圖表、建模工具等,需要的朋友可以參考下2015-12-12
簡(jiǎn)單實(shí)現(xiàn)js鼠標(biāo)跟隨效果
這篇文章主要教大家如何簡(jiǎn)單實(shí)現(xiàn)js鼠標(biāo)跟隨效果,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2017-07-07

