【JS】可選鏈操作符(?.)及其使用方法與場景 | 您所在的位置:網(wǎng)站首頁 › 屬龍的女孩什么時(shí)辰出生最好 › 【JS】可選鏈操作符(?.)及其使用方法與場景 |
可選鏈運算符(?.)
簡介
? 可選鏈運算符(?.)允許讀取位于連接對象鏈深處的屬性的值,而不必明確驗證鏈中的每個引用是否有效。?. 運算符的功能類似于 . 鏈式運算符,不同之處在于,在引用為空 (nullish ) (null 或者 undefined) 的情況下不會引起錯誤,該表達式短路返回值是 undefined。與函數(shù)調(diào)用一起使用時,如果給定的函數(shù)不存在,則返回 undefined。 ? 當嘗試訪問可能不存在的對象屬性時,可選鏈運算符將會使表達式更短、更簡明。在探索一個對象的內(nèi)容時,如果不能確定哪些屬性必定存在,可選鏈運算符也是很有幫助的。 語法 obj.val?.prop obj.val?.[expr] objc?.(args) 不使用可選鏈作符的寫法? 通過連接的對象的引用或函數(shù)可能是 undefined 或 null 時,可選鏈運算符提供了一種方法來簡化被連接對象的值訪問。 ? 比如,思考一個存在嵌套結(jié)構(gòu)的對象 obj。不使用可選鏈的話,查找一個深度嵌套的子屬性時,需要驗證之間的引用,例如: let nestedProp = obj.first && obj.first.second;? 為了避免報錯,在訪問obj.first.second之前,要保證 obj.first 的值既不是 null,也不是 undefined。如果只是直接訪問 obj.first.second,而不對 obj.first 進行校驗,則有可能拋出錯誤。 ? 有了可選鏈運算符(?.),在訪問 obj.first.second 之前,不再需要明確地校驗 obj.first 的狀態(tài),再并用短路計算獲取最終結(jié)果: let nestedProp = obj.first?.second;? 通過使用 ?. 運算符取代 . 運算符,JavaScript 會在嘗試訪問 obj.first.second 之前,先隱式地檢查并確定 obj.first 既不是 null 也不是 undefined。如果obj.first 是 null 或者 undefined,表達式將會短路計算直接返回 undefined。 ? 這等價于以下表達式,但實際上沒有創(chuàng)建臨時變量: let temp = obj.first; let nestedProp = temp === null || temp === undefined ? undefined : temp.second; 可選鏈與函數(shù)調(diào)用? 當嘗試調(diào)用一個可能不存在的方法時也可以使用可選鏈。這將是很有幫助的,比如,當使用一個 API 的方法可能不可用時,要么因為實現(xiàn)的版本問題要么因為當前用戶的設(shè)備不支持該功能。 ? 函數(shù)調(diào)用時如果被調(diào)用的方法不存在,使用可選鏈可以使表達式自動返回undefined而不是拋出一個異常。 let result = someInterface.customMethod?.();如果存在一個屬性名且不是函數(shù),使用 ?. 仍然會產(chǎn)生一個 TypeError 異常 (x.y is not a function). 備注: 如果 someInterface 自身是 null 或者 undefined ,異常 TypeError 仍會被拋出 someInterface is null 如果你希望允許 someInterface 也為 null 或者 undefined ,那么你需要像這樣寫 someInterface?.customMethod?.() 處理可選的回調(diào)函數(shù)或者事件處理器如果使用解構(gòu)賦值來解構(gòu)的一個對象的回調(diào)函數(shù)或 fetch 方法,你可能得到不能當做函數(shù)直接調(diào)用的不存在的值,除非你已經(jīng)校驗了他們的存在性。使用?.的你可以忽略這些額外的校驗: // ES2019 的寫法 function doSomething(onContent, onError) { try { // ... do something with the data } catch (err) { if (onError) { // 校驗 onError 是否真的存在 onError(err.message); } } } // 使用可選鏈進行函數(shù)調(diào)用 function doSomething(onContent, onError) { try { // ... do something with the data } catch (err) { onError?.(err.message); // 如果 onError 是 undefined 也不會有異常 } } 可選鏈和表達式當使用方括號與屬性名的形式來訪問屬性時,你也可以使用可選鏈運算符: let nestedProp = obj?.["prop" + "Name"]; 可選鏈不能用于賦值 let object = {}; object?.property = 1; // Uncaught SyntaxError: Invalid left-hand side in assignment 可選鏈訪問數(shù)組元素 let arrayItem = arr?.[42]; 示例 基本例子如下的例子在一個不含 bar 成員的 Map 中查找 bar 成員的 name 屬性,因此結(jié)果是 undefined。 let myMap = new Map(); myMap.set("foo", { name: "baz", desc: "inga" }); let nameBar = myMap.get("bar")?.name; 短路計算當在表達式中使用可選鏈時,如果左作數(shù)是 null 或 undefined,表達式將不會被計算,例如: let potentiallyNullObj = null; let x = 0; let prop = potentiallyNullObj?.[x++]; console.log(x); // x 將不會被遞增,依舊輸出 0 連用可選鏈運算符可以連續(xù)使用可選鏈讀取多層嵌套結(jié)構(gòu): let customer = { name: "Carl", details: { age: 82, location: "Paradise Falls", // details 的 address 屬性未有定義 }, }; let customerCity = customer.details?.address?.city; // … 可選鏈也可以和函數(shù)調(diào)用一起使用 let duration = vacations.trip?.getTime?.(); 使用空值合并運算符空值合并運算符可以在使用可選鏈時設(shè)置一個默認值: let customer = { name: "Carl", details: { age: 82 }, }; let customerCity = customer?.city ?? "暗之城"; console.log(customerCity); // “暗之城” 總結(jié)? 使用可選鏈作符可以避免由于調(diào)用對象不存在的屬性或方法導(dǎo)致的報錯,報錯有可能導(dǎo)致程序無法正常執(zhí)行。 |
今日新聞 |
推薦新聞 |
專題文章 |
CopyRight 2018-2019 實驗室設(shè)備網(wǎng) 版權(quán)所有 |