您好,登錄后才能下訂單哦!
JavaScript 從成立之初就已經走了很長一段路,提供了許多新的功能,這些功能是專門設計來使該語言更加人性化和提升效率。以下是我最近發現的一些有趣的JavaScript 新增內容。其中一些功能已在 Node,Chrome,Firefox 和 Safari 中可用,而其他功能仍處于建議階段。
Optional chaining 可選鏈使用??.
?操作符來表示,Optional Chaining 使我們能檢查一個對象上面是否存在某屬性。其它一些語言有類似的特性。例如 C# 有 Null Conditional 操作符。而 JavaScript 的 Optional chaining 在需要深度訪問嵌套對象屬性時就特別有用。
當我們在訪問對象的屬性前,我們需要用??.
?操作符來確定該屬性是否存在。
首先看看下面代碼:
const?users?=?[ ??{???name:?"Olagunju?Gbolahan",???occupation:?"Software?Developer", ???sayName(){????console.log(`my?name?is?${this.name}`); ???},???address:?{?office:?"New?York"?} ??}, ??{?name:?"Olawaseyi?Moses"?}, ??{?name:?"Tunde?Ednut"?} ];
在該數組對象中,第二個對象是 secondUser:
const?secondUser?=?users[1];
我們需要知道該用戶的辦公室地址,在沒有 Optional chaining 之前,我們需要使用一種很低效的方式來驗證該屬性是否已存在:
const?theAddress?=?secondUser.address?&&?secondUser.address.office;console.log(theAddress);?//?undefined
如果我們是一個深度嵌套的對象,那就必須通過 && 操作符來判斷每一層的對象是否有效:
但是有了 optional chaining ,代碼便可簡化如下:
const?theAddress?=?secondUser?.address?.office;console.log(theAddress);?//?undefined
我們還可以使用 optional chaining 來確認對象的某個方法是否存在:
const?firstUser?=?users[0];console.log(firstUser.sayName?.());?//?我的名字是?Olagunju?Gbolahan
如果方法名不存在的話,它會簡單的返回?undefined
?:
console.log(firstUser.sayOccupation?.());?//?undefined
目前該特性尚未添加到 JavaScript 規范中,目前還處于草案建議階段。
你可以通過?babel-plugin-proposal-optional-chaining?這個插件來實現相同功能。
你也可以閱讀 《Optional Chaining 特性進入 Stage 3,TypeScript 跟進》?這篇文章來了解更多關于該特性的進展。
當我們事先知道錯誤將是什么,并且我們不希望冗余未使用的變量時,此功能將派上用場。?
首先看看常規的 try 和 catch 的代碼塊:
try?{??const?parsedJsonData?=?JSON.parse(obj); }?catch?(error)?{??//obj?變量在使用時沒有進行定義 ??console.log(obj); }
而通過錯誤捕獲綁定,我們無需提供未使用的變量,特別是當我們已經為 try 塊提供默認處理的情況下:
function?getName?()?{??let?name?=?"Gbolahan?Olagunju";??try?{ ????name?=?obj.details.name ??}?catch?{}??console.log(name); }
這是對 JavaScript 的擬議補充之一,目前處于第1階段。本質上,它有助于使對同一參數的多個函數調用可讀。
它通過將表達式的值作為參數傳遞給函數來實現。
在沒有管道運算符的情況下調用以下函數|>
。
const?capitalize?=?(input)?=>??input[0].toUpperCase()?+?input.substring(1);const?removeSpaces?=?(input)?=>?input.trim();const?repeat?=?(input)?=>?`${input},?${input}`;const?withoutpipe?=?repeat(capitalize(removeSpaces('????i?am?gbols????')));console.log(withoutpipe);?//?I?am?gbols,?I?am?gbols
而通過管道操作符,可讀性大幅提升:
const?withpipe?=?'????i?am?gbols????' ????????????????|>?removeSpaces ????????????????|>?capitalize ????????????????|>?repeat;console.log(withpipe);?//?//?I?am?gbols,?I?am?gbols
這兩個方法在之前被命名為?trimRight 和 trimLeft,但在 ES2019 中將名字修改為?trimStart 和 trimEnd ,表述更加直觀:
示例代碼:
let?message?=?"?????Welcome?to?LogRocket??????"; message.trimStart();?//?"Welcome?to?LogRocket??????"message.trimEnd();?//?"Welcome?to?LogRocket";
在聊 Object.fromEntries 之前,有必要先看看 Object.entries.
Object.entries 是在 ES2017 規范中引入的,用于將對象轉成數組,并可通過數組相關的函數進行訪問。
示例代碼:
const?devs?=?{??gbols:?5,??andrew:?3,??kelani:?10,??dafe:?8, };const?arrOfDevs?=?Object.entries(devs);console.log(arrOfDevs);//[//??["gbols",?5]//??["andrew",?3]//??["kelani",?10]//??["dafe",?8]//]
然后我們可以使用?filter
?方法來獲取數組中超過 5 年經驗的對象:
const?expDevs?=?arrOfDevs.filter(([name,?yrsOfExp])?=>?yrsOfExp?>?5);console.log(expDevs);//[//??["kelani",?10]//??["dafe",?8]//]
那么就會有一個新的問題:沒有一個簡單的方法將最新的數組重新變成對象。通常我們需要自己編寫代碼將數組變成對象:
const?expDevsObj?=?{};for?(let?[name,?yrsOfExp]?of?expDevs)?{ expDevsObj[name]?=?yrsOfExp; }console.log(expDevsObj);//{ ?//dafe:?8 ?//kelani:?10//}
但是現在通過 Object.fromEntries 就可以把這個過程極大簡化:
console.log(Object.fromEntries(expDevs));//{ ?//dafe:?8 ?//kelani:?10//}
很多使用我們需要處理深度嵌套的數組,這個時候將數組展平就特別重要。
先看看如下代碼:
const?developers?=?[ ??{????name:?'Gbolahan?Olagunju',????yrsOfExp:?6,????stacks:?['Javascript',?'NodeJs',?['ReactJs',?['ExpressJs',?'PostgresSql']]] ??}, ??{????name:?'Daniel?Show',????yrsOfExp:?2,????stacks:?['Ruby',?'Jest',?['Rails',?['JQuery',?'MySql']]] ??}, ??{????name:?'Edafe?Emunotor',????yrsOfExp:?9,????stacks:?['PHP',?'Lumen',?['Angular',?'NgRx']] ??} ];const?allStacks?=?developers.map(({stacks})?=>?stacks);console.log(allStacks);//?[//?['Javascript',?'NodeJs',?['ReactJs',?['ExpressJs',?'PostgresSql']]]//?['Ruby',?'Jest',?['Rails',?['JQuery',?'MySql']]]//?['PHP',?'Lumen',?['Angular',?'NgRx']]//?]
allstacks
?變量包含深度嵌套的數組,為了將該數組展平,我們可以使用 Array.prototype.flat 方法。
示例代碼:
const?flatSingle?=?allStacks.flat();console.log(flatSingle);//[//?"JavaScript",//??"NodeJs",//?['ReactJs',?['ExpressJs',?'PostgresSql']]]//?"Ruby",//?"Jest",//?['Rails',?['JQuery',?'MySql']]]//?"PHP",//?"Lumen"http://?["Angular",?"NgRx"]//]
從上面代碼可以推斷出數組被展平了一層深,這是 array.prototype.flat 的默認參數。
我們可以向flat方法傳遞一個參數,以確定要展平的程度。
defaults 參數的值為1。為了完全展平數組,我們可以傳遞一個無窮大的參數。參數 infinity 使數組完全變平,與數組的深度無關。
示例代碼:
const?completelyFlat?=?allStacks.flat(Infinity);console.log(completelyFlat);//[//?"JavaScript",//?"NodeJs",//?"ReactJs",//?"ExpressJs",//?"PostgresSql",//?"Ruby",//?"Jest",//?"Rails",//?"JQuery",//?"MySql",//?"PHP",//?"Lumen",//?"Angular",//?"NgRx"http://]
FlatMap 相當于將 map 方法和 flat 方法合并起來,并默認使用深度為 1 的新方法。相當于是以更簡潔的代碼實現兩種邏輯的組合。
下面是一個簡單使用 map 和 flatMap 的代碼:
let?arr?=?['my?name?is?Gbols',?'?',?'and?i?am?great?developer'];? console.log(arr.map(word?=>?word.split('?')));//[//?["my",?"name",?"is",?"Gbols"],//?["",?""],//?["and",?"i",?"am",?"great",?"developer"]//]console.log(arr.flatMap(word?=>?word.split('?')));//[?"my"http://??"name"http://??"is"http://??"Gbols"http://???""http://???""http://???"and"http://???"i"http://???"am"http://???"great"http://???"developer"http://]
在這篇文字中,我們詳細介紹了一些 JavaScript 最新添加的新特性,這些新的特性通過減少冗長的代碼以及提升代碼的可讀性來增強了開發者的體驗。不過還有很多新的特性在本文中沒有涉及,歡迎大家補充和分享。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。