摘要:到年月,一個新的可選鏈提案已經進入第三階段,這是一個很好的改進。可選鏈接改變了從深層對象結構訪問屬性的方式。咱們來看看可選鏈如何解決這個問題,以減少冗余的代碼。該對象包含必填屬性,以及可選的和。可選鏈運算符可防止拋出。
為了保證的可讀性,本文采用意譯而非直譯。
想閱讀更多優質文章請猛戳GitHub博客,一年百來篇優質文章等著你!
JS的一些特性極大地改變了咱們的編碼方式。從ES6年開始,對咱們代碼影響最大的特性的解 、箭頭函數、類和模塊系統。
到2019年8月,一個新的可選鏈提案已經進入第三階段,這是一個很好的改進。可選鏈接改變了從深層對象結構訪問屬性的方式。
來看看這是又是什么騷操作。
這個禮拜《大遷世界》有抽獎活動,獎品:專欄 《左耳聽風》 x3, 技術書 x5,歡迎關注回復:抽獎問題
由于JS的動態特性,對象可以具有多層不同的嵌套對象結構。
通常,當咱們處理以下這些對象時:
獲取遠程JSON數據
使用配置對象
有可選屬性
雖然JS為對象支持不同層次數據結構,但是在訪問此類對象的屬性時,復雜性也隨著增加。
bigObject可以在運行時擁有不同的屬性集
// 嵌套版本 const bigObject = { // ... prop1: { //... prop2: { // ... value: "Some value" } } }; // 簡單版本 const bigObject = { // ... prop1: { // Nothing here } };
因此,必須手動檢查屬性是否存在
if (bigObject && bigObject.prop1 != null && bigObject.prop1.prop2 != null) { let result = bigObject.prop1.prop2.value; }
這樣寫太過冗長了,最好避免寫它。
咱們來看看可選鏈如何解決這個問題,以減少冗余的代碼。
2. 易于深入訪問屬性設計一個保存電影信息的對象。 該對象包含必填title屬性,以及可選的director和actors。
movieSmall對象僅包含title,而movieFull包含完整的屬性集:
const movieSmall = { title: "Heat" }; const movieFull = { title: "Blade Runner", director: { name: "Ridley Scott" }, actors: [{ name: "Harrison Ford" }, { name: "Rutger Hauer" }] };
寫一個獲取director的函數。 請記住,director 可能不存在。
function getDirector(movie) { if (movie.director != null) { return movie.director.name; } } getDirector(movieSmall); // => undefined getDirector(movieFull); // => "Ridley Scott"
if(movie.director){...}條件用于驗證是否定義了director屬性。 如果沒有這個預防措施,在訪問movieSmall對象的director時,JS會拋出TypeError: Cannot read property "name" of undefined。
這種場景最適合使用可選鏈的功能了,如下所示,代碼將簡潔很多。
function getDirector(movie) { return movie.director?.name; } getDirector(movieSmall); // => undefined getDirector(movieFull); // => "Ridley Scott"
在movie.director?.name表達式中可以找到?.可選的鏈接操作符。
在movieSmall中,沒有director屬性。 因此,movie.director?.name的的結果為undefined。 可選鏈運算符可防止拋出 TypeError: Cannot read property "name" of undefined。
簡單地說,代碼片段:
let name = movie.director?.name;
等價于
let name; if (movie.director != null) { name = movie.director.name; }
?.通過減少兩行代碼簡化getDirector()函數,這就是為什么我喜歡可選鏈的原因。
2.1 數組項可選的鏈功能可以做得更多。可以自由地在同一個表達式中使用多個可選的鏈接操作符,甚至可以使用它安全地訪問數組項。
下一個任務是編寫一個函數,返回電影的actors中的name。
在movie對象中,actors數組可以是空的,甚至是缺失的,因此必須添加額外的條件來判空。
function getLeadingActor(movie) { if (movie.actors && movie.actors.length > 0) { return movie.actors[0].name; } } getLeadingActor(movieSmall); // => undefined getLeadingActor(movieFull); // => "Harrison Ford"
if (movie.actors && movies.actors.length > 0) {...}條件主要判斷movie包含actors屬性,并且此屬性至少有一個actor。
使用可選鏈接,同樣代碼也簡潔了很了,如下:
function getLeadingActor(movie) { return movie.actors?.[0]?.name; } getLeadingActor(movieSmall); // => undefined getLeadingActor(movieFull); // => "Harrison Ford"
actors?. 確保actors屬性存在, [0]?.確保列表中存在第一個actor。
3.雙問號操作符一個名為nullish coalescing operator的新提議? 處理undefined或null,將它們默認為特定值。
表達式變量?? 如果變量undefined或為null,則默認值為指定的值。
const noValue = undefined; const value = "Hello"; noValue ?? "Nothing"; // => "Nothing" value ?? "Nothing"; // => "Hello"
接著使用??來優化一下 getLeading()函數,當movie對象中沒有actor時返回“Unknown actor”
function getLeadingActor(movie) { return movie.actors?.[0]?.name ?? "Unknown actor"; } getLeadingActor(movieSmall); // => "Unknown actor" getLeadingActor(movieFull); // => "Harrison Ford"4. 可選鏈的三種形式
咱們可以使用以下3種形式的可選鏈。
第一種: object?.property 用于訪問靜態屬性:
const object = null; object?.property; // => undefined
第二種:object?.[expression] 用于訪問動態屬性或數組項:
// 其一 const object = null; const name = "property"; object?.[name]; // => undefined // 其二 const array = null; array?.[0]; // => undefined
第三種:object?.([arg1, [arg2, ...]]) 執行一個對象方法
const object = null; object?.method("Some value"); // => undefined
將這三種組合起來創建一個可選鏈:
const value = object.maybeUndefinedProp?.maybeNull()?.[propName];5.短路:遇到 null/undefined 停止
可選鏈接運算符的有趣之處在于,只要在左側leftHandSide?.rightHandSide遇到無效值,右側訪問就會停止,這稱為短路。
看看例子:
const nothing = null; let index = 0; nothing?.[index++]; // => undefined index; // => 06. 何時使用可選鏈
不要急于使用可選的鏈操作符來訪問任何類型的屬性:這會導致錯誤的使用。
6.1訪問潛在無效的屬性?.一般使用在可能為空的屬性:maybeNullish?.prop。在確定屬性不為空的情況下,使用屬性訪問器:.property或[propExpression]。
// 好 function logMovie(movie) { console.log(movie.director?.name); console.log(movie.title); } // 不好 function logMovie(movie) { // director needs optional chaining console.log(movie.director.name); // movie doesn"t need optional chaining console.log(movie?.title); }6.2 通常有更好的選擇
以下函數hasPadding()接收可選padding屬性的樣式對象。 padding具有left,top,right,bottom可選屬性。
嘗試使用可選的鏈操作符:
function hasPadding({ padding }) { const top = padding?.top ?? 0; const right = padding?.right ?? 0; const bottom = padding?.bottom ?? 0; const left = padding?.left ?? 0; return left + top + right + bottom !== 0; } hasPadding({ color: "black" }); // => false hasPadding({ padding: { left: 0 } }); // => false hasPadding({ padding: { right: 10 }}); // => true
雖然函數正確地確定了元素是否有padding,但是對于每個屬性使用可選的鏈有點過于麻煩了。
更好的方法是使用對象擴展操作符將padding對象默認為零值
function hasPadding({ padding }) { const p = { top: 0, right: 0, bottom: 0, left: 0, ...padding }; return p.top + p.left + p.right + p.bottom !== 0; } hasPadding({ color: "black" }); // => false hasPadding({ padding: { left: 0 } }); // => false hasPadding({ padding: { right: 10 }}); // => true
這個就比可選鏈來的更簡潔。
代碼部署后可能存在的BUG沒法實時知道,事后為了解決這些BUG,花了大量的時間進行log 調試,這邊順便給大家推薦一個好用的BUG監控工具 Fundebug。
原文:https://dmitripavlutin.com/ja...
交流干貨系列文章匯總如下,覺得不錯點個Star,歡迎 加群 互相學習。
https://github.com/qq44924588...
我是小智,公眾號「大遷世界」作者,對前端技術保持學習愛好者。我會經常分享自己所學所看的干貨,在進階的路上,共勉!
關注公眾號,后臺回復福利,即可看到福利,你懂的。
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/106986.html
摘要:今天決定給自己的站點配置,配置完成后發現不能正常訪問,思來想去發現是未開啟端口。這也是不指定規則序號時的默認方式。參數給出一個合法的目標。給出當前命令語法非常簡短的說明。 今天決定給自己的站點配置SSL,配置完成后發現不能正常訪問,思來想去發現是未開啟443端口。 Linux防火墻開放特定端口 方法一 找到/etc/sysconfig/iptables文件加入如下代碼,并保存 -A I...
摘要:如果大家閱讀過我之前寫的一篇關于解構的文章,那一定會了解到解構達到數據防御功能,那么本文要介紹的是另一種數據防御方式可選鏈。什么是允許我們檢查對象是否存在,然后才試圖訪問它的屬性。如何使用目前在階段。 如果大家閱讀過我之前寫的一篇關于ES6解構的文章,那一定會了解到解構達到數據防御功能,那么本文要介紹的是另一種數據防御方式Optional Chaining(可選鏈)。 什么是Optio...
閱讀 1118·2021-10-09 09:43
閱讀 18475·2021-09-22 15:52
閱讀 1059·2019-08-30 15:44
閱讀 3050·2019-08-30 15:44
閱讀 3244·2019-08-26 14:07
閱讀 904·2019-08-26 13:55
閱讀 2566·2019-08-26 13:41
閱讀 3087·2019-08-26 13:29