您好,登錄后才能下訂單哦!
JavaScript 從成立之初就已經(jīng)走了很長一段路,提供了許多新的功能,這些功能是專門設(shè)計(jì)來使該語言更加人性化和提升效率。以下是我最近發(fā)現(xiàn)的一些有趣的JavaScript 新增內(nèi)容。其中一些功能已在 Node,Chrome,F(xiàn)irefox 和 Safari 中可用,而其他功能仍處于建議階段。
Optional chaining 可選鏈?zhǔn)褂??.
?操作符來表示,Optional Chaining 使我們能檢查一個(gè)對象上面是否存在某屬性。其它一些語言有類似的特性。例如 C# 有 Null Conditional 操作符。而 JavaScript 的 Optional chaining 在需要深度訪問嵌套對象屬性時(shí)就特別有用。
當(dāng)我們在訪問對象的屬性前,我們需要用??.
?操作符來確定該屬性是否存在。
首先看看下面代碼:
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"?} ];
在該數(shù)組對象中,第二個(gè)對象是 secondUser:
const?secondUser?=?users[1];
我們需要知道該用戶的辦公室地址,在沒有 Optional chaining 之前,我們需要使用一種很低效的方式來驗(yàn)證該屬性是否已存在:
const?theAddress?=?secondUser.address?&&?secondUser.address.office;console.log(theAddress);?//?undefined
如果我們是一個(gè)深度嵌套的對象,那就必須通過 && 操作符來判斷每一層的對象是否有效:
但是有了 optional chaining ,代碼便可簡化如下:
const?theAddress?=?secondUser?.address?.office;console.log(theAddress);?//?undefined
我們還可以使用 optional chaining 來確認(rèn)對象的某個(gè)方法是否存在:
const?firstUser?=?users[0];console.log(firstUser.sayName?.());?//?我的名字是?Olagunju?Gbolahan
如果方法名不存在的話,它會(huì)簡單的返回?undefined
?:
console.log(firstUser.sayOccupation?.());?//?undefined
目前該特性尚未添加到 JavaScript 規(guī)范中,目前還處于草案建議階段。
你可以通過?babel-plugin-proposal-optional-chaining?這個(gè)插件來實(shí)現(xiàn)相同功能。
你也可以閱讀 《Optional Chaining 特性進(jìn)入 Stage 3,TypeScript 跟進(jìn)》?這篇文章來了解更多關(guān)于該特性的進(jìn)展。
當(dāng)我們事先知道錯(cuò)誤將是什么,并且我們不希望冗余未使用的變量時(shí),此功能將派上用場。?
首先看看常規(guī)的 try 和 catch 的代碼塊:
try?{??const?parsedJsonData?=?JSON.parse(obj); }?catch?(error)?{??//obj?變量在使用時(shí)沒有進(jìn)行定義 ??console.log(obj); }
而通過錯(cuò)誤捕獲綁定,我們無需提供未使用的變量,特別是當(dāng)我們已經(jīng)為 try 塊提供默認(rèn)處理的情況下:
function?getName?()?{??let?name?=?"Gbolahan?Olagunju";??try?{ ????name?=?obj.details.name ??}?catch?{}??console.log(name); }
這是對 JavaScript 的擬議補(bǔ)充之一,目前處于第1階段。本質(zhì)上,它有助于使對同一參數(shù)的多個(gè)函數(shù)調(diào)用可讀。
它通過將表達(dá)式的值作為參數(shù)傳遞給函數(shù)來實(shí)現(xiàn)。
在沒有管道運(yùn)算符的情況下調(diào)用以下函數(shù)|>
。
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
這兩個(gè)方法在之前被命名為?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 規(guī)范中引入的,用于將對象轉(zhuǎn)成數(shù)組,并可通過數(shù)組相關(guān)的函數(shù)進(jìn)行訪問。
示例代碼:
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
?方法來獲取數(shù)組中超過 5 年經(jīng)驗(yàn)的對象:
const?expDevs?=?arrOfDevs.filter(([name,?yrsOfExp])?=>?yrsOfExp?>?5);console.log(expDevs);//[//??["kelani",?10]//??["dafe",?8]//]
那么就會(huì)有一個(gè)新的問題:沒有一個(gè)簡單的方法將最新的數(shù)組重新變成對象。通常我們需要自己編寫代碼將數(shù)組變成對象:
const?expDevsObj?=?{};for?(let?[name,?yrsOfExp]?of?expDevs)?{ expDevsObj[name]?=?yrsOfExp; }console.log(expDevsObj);//{ ?//dafe:?8 ?//kelani:?10//}
但是現(xiàn)在通過 Object.fromEntries 就可以把這個(gè)過程極大簡化:
console.log(Object.fromEntries(expDevs));//{ ?//dafe:?8 ?//kelani:?10//}
很多使用我們需要處理深度嵌套的數(shù)組,這個(gè)時(shí)候?qū)?shù)組展平就特別重要。
先看看如下代碼:
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
?變量包含深度嵌套的數(shù)組,為了將該數(shù)組展平,我們可以使用 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"]//]
從上面代碼可以推斷出數(shù)組被展平了一層深,這是 array.prototype.flat 的默認(rèn)參數(shù)。
我們可以向flat方法傳遞一個(gè)參數(shù),以確定要展平的程度。
defaults 參數(shù)的值為1。為了完全展平數(shù)組,我們可以傳遞一個(gè)無窮大的參數(shù)。參數(shù) infinity 使數(shù)組完全變平,與數(shù)組的深度無關(guān)。
示例代碼:
const?completelyFlat?=?allStacks.flat(Infinity);console.log(completelyFlat);//[//?"JavaScript",//?"NodeJs",//?"ReactJs",//?"ExpressJs",//?"PostgresSql",//?"Ruby",//?"Jest",//?"Rails",//?"JQuery",//?"MySql",//?"PHP",//?"Lumen",//?"Angular",//?"NgRx"http://]
FlatMap 相當(dāng)于將 map 方法和 flat 方法合并起來,并默認(rèn)使用深度為 1 的新方法。相當(dāng)于是以更簡潔的代碼實(shí)現(xiàn)兩種邏輯的組合。
下面是一個(gè)簡單使用 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://]
在這篇文字中,我們詳細(xì)介紹了一些 JavaScript 最新添加的新特性,這些新的特性通過減少冗長的代碼以及提升代碼的可讀性來增強(qiáng)了開發(fā)者的體驗(yàn)。不過還有很多新的特性在本文中沒有涉及,歡迎大家補(bǔ)充和分享。
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。