譯者:前端小智原文:https://blog.logrocket.com/5-es2019-features-you-can-use-today/
譯者:前端小智
為了保證可讀性,本文採用意譯而非直譯。
ECMAScript 2015,也稱為ES6,是一個花了6年時間完成的主要版本。從那時起,負責ECMAScript標準開發的技術委員會39 (TC39)每年都會發布該標準的新版本。這個年度發布週期簡化了這個過程,並使新特性快速可用,JavaScript社區對此表示歡迎。
今年,ECMAScript 2019(簡稱ES2019)將會發布。 新功能包括 Object.fromEntries(), trimStart(), trimEnd(), flat(), flatMap(),symbol對象的description屬性,可選的 catch綁定等。
Object.fromEntries()
trimStart()
trimEnd()
flat()
flatMap()
catch
好消息是這些功能已經在最新版本的Firefox和Chrome中實現,並且它們也可以被轉換,以便舊版瀏覽器能夠處理它們。
在JavaScript中,將數據從一種格式轉換為另一種格式非常常見。 為了便於將對象轉換為數組,ES2017引入了 Object.entrie()方法。 此方法將對象作為參數,並以 [key,value]的形式返回對象自己的可枚舉字元串鍵控屬性對的數組。 例如:
Object.entrie()
[key,value]
const obj = {one: 1, two: 2, three: 3};
console.log(Object.entries(obj)); // => [["one", 1], ["two", 2], ["three", 3]]
但是如果我們想要做相反的事情並將鍵值對列錶轉換為對象呢? 某些編程語言(如Python)為此提供了 dict()函數。 在 Underscore.js和Lodash中還有 _.fromPairs函數。
dict()
Underscore.js
_.fromPairs
ES2019引入 Object.fromEntries()方法為JavaScript帶來類似的功能, 此靜態方法允許你輕鬆地將鍵值對列錶轉換為對象:
const myArray = [[one, 1], [two, 2], [three, 3]]; const obj = Object.fromEntries(myArray);
console.log(obj); // => {one: 1, two: 2, three: 3}
如你所見, Object.fromEntries()與 Object.entries()所做的事情正好相反。 雖然以前可以實現Object.fromEntries()相同的功能,但它實現方式有些複雜:
Object.entries()
const myArray = [[one, 1], [two, 2], [three, 3]]; const Array.from(myArray).reduce((acc, [key, val]) => Object.assign(acc, {[key]: val}), {})
請記住,傳遞給 Object.fromEntries()的參數可以是實現可迭代協議的任何對象,只要它返回一個兩元素,類似於數組的對象即可。
例如,在以下代碼中, Object.fromEntries() 將Map對象作為參數,並創建一個新對象,其鍵和對應值由Map中的對給出:
const map = new Map(); map.set(one, 1); map.set(two, 2);
const obj = Object.fromEntries(map);
console.log(obj); // => {one: 1, two: 2}
Object.fromEntries() 方法對於轉換對象也非常有用,思考以下代碼:
const obj = {a: 4, b: 9, c: 16};
// 將對象轉換為數組 const arr = Object.entries(obj);
// 計算數字的平方根 const map = arr.map(([key, val]) => [key, Math.sqrt(val)]);
// 將數組轉換回對象 const obj2 = Object.fromEntries(map);
console.log(obj2); // => {a: 2, b: 3, c: 4}
上述代碼將對象中的值轉換為其平方根。 為此,它首先將對象轉換為數組,然後使用 map()方法獲取數組中值的平方根,結果是可以轉換回對象的數組。
map()
使用 Object.fromEntries()的另一種情況是處理URL的查詢字元串,如本例所示
const paramsString = param1=foo¶m2=baz; const searchParams = new URLSearchParams(paramsString);
Object.fromEntries(searchParams); // => {param1: "foo", param2: "baz"}
此代碼中,查詢字元串將傳遞給 URLSearchParams()構造函數。 然後將返回值(即 URLSearchParams對象實例)傳遞給 Object.fromEntries() 方法,結果是一個包含每個參數作為屬性的對象。
URLSearchParams()
URLSearchParams
Object.fromEntries() 方法目前是第4階段提案,這意味著它已準備好包含在ES2019標準中。
trimStart()和 trimEnd()方法在實現與 trimLeft()和 trimRight()相同。這些方法目前處於第4階段,將被添加到規範中,以便與 padStart()和 padEnd()保持一致,來看一些例子:
trimLeft()
trimRight()
padStart()
padEnd()
const str = " string ";
// es2019 console.log(str.trimStart()); // => "string " console.log(str.trimEnd()); // => " string" // 相同結果 console.log(str.trimLeft()); // => "string " console.log(str.trimRight()); // => " string"
對於Web兼容性, trimLeft() 和 trimRight() 將保留為 trimStart() 和 trimEnd() 的別名。
flat() 方法可以將多維數組展平成一維數組
const arr = [a, b, [c, d]]; const flattened = arr.flat();
console.log(flattened); // => ["a", "b", "c", "d"]
以前,我們經常使用 reduce()或 concat()來展平多維數組:
reduce()
concat()
const arr = [a, b, [c, d]]; const flattend = [].concat.apply([], arr);
// or // const flattened = [].concat(...arr); console.log(flattened); // => ["a", "b", "c", "d"]
請注意,如果提供的數組中有空值,它們會被丟棄:
const arr = [a, , , b, [c, d]]; const flattened = arr.flat();
flat() 還接受一個可選參數,該參數指定嵌套數組應該被展平的級別數。 如果未提供參數,則將使用默認值 1:
1
const arr = [10, [20, [30]]];
console.log(arr.flat()); // => [10, 20, [30]] console.log(arr.flat(1)); // => [10, 20, [30]] console.log(arr.flat(2)); // => [10, 20, 30]
flatMap() 方法將 map()和 flat()組合成一個方法。 它首先使用提供的函數的返回值創建一個新數組,然後連接該數組的所有子數組元素。 來個例子:
const arr = [4.25, 19.99, 25.5];
console.log(arr.map(value => [Math.round(value)])); // => [[4], [20], [26]] console.log(arr.flatMap(value => [Math.round(value)])); // => [4, 20, 26]
數組將被展平的深度級別為 1.如果要從結果中刪除項目,只需返回一個空數組:
const arr = [[7.1], [8.1], [9.1], [10.1], [11.1]];
// do not include items bigger than 9 arr.flatMap(value => { if (value >= 10) { return []; } else { return Math.round(value); } });
// returns: // => [7, 8, 9]
除了正在處理的當前元素外,回調函數還將接收元素的索引和對數組本身的引用。 flat()和 flatMap()方法目前處於第4階段。
在創建Symbol時,可以為調試目的向其添加 description (描述)。有時候,能夠直接訪問代碼中的 description 是很有用的。
description
ES2019 中為 Symbol對象添加了只讀屬性 description ,該對象返回包含 Symbol描述的字元串。
Symbol
let sym = Symbol(foo); console.log(sym.description); // => foo sym = Symbol(); console.log(sym.description); // => undefined // create a global symbol sym = Symbol.for(bar); console.log(sym.description); // => bar
trycatch 語句中的 catch有時候並沒有用,思考下面代碼:
trycatch
try { // 使用瀏覽器可能尚未實現的功能 } catch (unused) { // 這裡回調函數中已經幫我們處理好的錯誤 }
此代碼中的 catch回調的信息並沒有用處。 但這樣寫是為了避免 SyntaxError錯誤。 ES2019可以省略 catch周圍的括弧:
SyntaxError
try { // ... } catch { // .... }
matchAll() 方法是ES2020 第4階段提議,它針對正則表達式返回所有匹配(包括捕獲組)的迭代器對象。
matchAll()
為了與 match()方法保持一致,TC39 選擇了「matchAll」而不是其他建議的名稱,例如 「matches」 或 Ruby的 「scan」。看個簡單的例子:
match()
const re = /(Dr. )w+/g; const str = Dr. Smith and Dr. Anderson; const matches = str.matchAll(re);
for (const match of matches) { console.log(match); }
// logs: // => ["Dr. Smith", "Dr. ", index: 0, input: "Dr. Smith and Dr. Anderson", groups: undefined] // => ["Dr. Anderson", "Dr. ", index: 14, input: "Dr. Smith and Dr. Anderson", groups: undefined]
此正則表達式中的捕獲組匹配字元「Dr」,後跟一個點和一個空格 。w+ 匹配任何單詞字元一次或多次。 並且 g標誌指示引擎在整個字元串中搜索模式。
。w+
g
之前,必須在循環中使用 exec()方法來實現相同的結果,這不是非常有效:
exec()
const re = /(Dr.) w+/g; const str = Dr. Smith and Dr. Anderson; let matches;
while ((matches = re.exec(str)) !== null) { console.log(matches); }
// logs: // => ["Dr. Smith", "Dr.", index: 0, input: "Dr. Smith and Dr. Anderson", groups: undefined] // => ["Dr. Anderson", "Dr.", index: 14, input: "Dr. Smith and Dr. Anderson", groups: undefined]
重要的是要注意儘管 match() 方法可以與全局標誌 g一起使用來訪問所有匹配,但它不提供匹配的捕獲組或索引位置。 比較以下代碼:
const re = /page (d+)/g; const str = page 2 and page 10;
console.log(str.match(re)); // => ["page 2", "page 10"] console.log(...str.matchAll(re)); // => ["page 2", "2", index: 0, input: "page 2 and page 10", groups: undefined] // => ["page 10", "10", index: 11, input: "page 2 and page 10", groups: undefined]
在這篇文章中,我們仔細研究了 ES2019 中引入的幾個關鍵特性,包括 Object.fromEntries(), trimStart(), trimEnd(), flat(), flatMap(), symbol 對象的description 屬性以及可選的 catch 。
symbol
儘管一些瀏覽器還沒有完全實現這些特性,但可以使用Babel和其他JavaScript轉換器,仍然可以在項目中使用它們。
乾貨系列文章匯總如下,覺得不錯點個Star,歡迎 加羣 互相學習。
https://github.com/qq449245884/xiaozhi
我是小智,公眾號「大遷世界」作者,對前端技術保持學習愛好者。我會經常分享自己所學所看的乾貨,在進階的路上,共勉!
關注公眾號,後臺回復福利,即可看到福利,你懂的。