翻譯:李冰 原文:http://www.zsoltnagy.eu/whats-new-in-es2019/
ES2019或ES10是JavaScript的2019版本。在2015年進行重大更新之後,JavaScript每年都在發展。開發人員可以獲得一小組有用的功能,這些功能可以幫助我們在創新與穩定性之間取得平衡。
您也可以在此博客中瞭解JavaScript的發展,因爲第一篇文章發佈於2015年。現在是時候從實際角度考察ES2019更新。像往常一樣,不要期望對理論上的極端情況進行冗長的描述。本文寧願加倍討論實際用例。
JavaScript兼容性表
如果您想查看每個JavaScript版本的完整更新列表,請查看此兼容性表。當我在最新的Google Chrome瀏覽器中查看更新時,我發現即使對於建議的ES2020版本,大多數測試也已通過。
請注意,您的代碼可能必須支持多個瀏覽器。因此,請考慮在您的應用程序中使用polyfills。
讓我們一一探索ES2019功能列表:
1. Object.fromEntries
回想一下Object.entries
ES2015:
Object.entries({first: 'Zsolt', last: 'Nagy'});
// [["first", "Zsolt"], ["last", "Nagy"]]
提供逆變換是很有意義的:
Object.fromEntries([["first", "Zsolt"], ["last", "Nagy"]]);
// {first: "Zsolt", last: "Nagy"}
除了使用數組之外,您還可以通過Map創建對象:
var postBoxes = new Map();
postBoxes.set('128', 'first message');
postBoxes.set('15', 'second message');
Object.fromEntries(postBoxes);
// {'15': "second message", '128': "first message"}
2.字符串修剪
假設給出了一個字符串,其中要插入的內容被空白字符(換行符,製表符,空格等)包圍:
const template = `
<h3>String trimming</h3>
`;
在早期版本的JavaScript中,已經可以進行修整:
template.trim()
// "<h3>String trimming</h3>"
在ES2019中,也可以只修剪字符串的左側或右側。
trimStart
並且trimLeft
在我們必須將文本(包括末尾的空格)插入特定位置時非常方便。trimEnd
並且trimRight
在我們必須在文本結尾之後插入一些內容時非常方便(例如,在= $0
突出顯示控制檯中DOM元素的標記之前顯示HTML標記)。- 還請注意ES2019
trimStart
和trimEnd
方法刪除了ES添加的填充padStart
和padEnd
:
3. Array.prototype.flat
所述flat
陣列的方法變平以下述方式排列:如果A
是我們的數組的元素,並且A
是一個數組,然後A
被取代...A
。
[1, 2, [3, [4, 5]]].flat()
變成
[1, 2, ...[3, [4, 5]]]
變成
[1, 2, 3, [4, 5]]
該flat
方法可以採用可選的數字參數。如果此參數爲1
,則展平將在一個級別上發生。換句話說,A.flat(1)
與等效A.flat()
。
如果提供的參數,flat
則該參數至少1
必須flattening
爲發生:
[[1]].flat(0)
住宿[[1]]
,[[1]].flat(1)
成爲[1]
。
當flat
具有大於的整數參數時1
,展平變爲遞歸操作,其中在每個遞歸級別上,的參數均flat
減小1
。
// Original call:
[1, 2, [3, [4, 5]]].flat(2)
// Move the flattening inside the array members
// of the flattened array:
[1, 2, ...[3, [4, 5].flat(1)]]
// Spread the values
[1, 2, 3, [4, 5].flat(1)]
// Flatten the [4, 5] array
[1, 2, 3, ...[4, 5]]
// Extract the values
[1, 2, 3, 4, 5]
flat
提供無限長深度展平的特殊情況:
A.flat(Infinity)
這種特殊情況很少使用,因爲開發人員應該知道他們的數據結構,這樣他們就已經知道需要平整多少個級別。在實踐中,最通常的情況是需要一種扁平化,因爲我們通常不從API檢索嵌套的多維數組。
練習:假設TicTacToe遊戲的狀態是以二維數組的形式給出的。將遊戲板轉換爲字符串9
以簡化計算。
const board = [
['X', 'O', '.'],
['.', 'O', '.'],
['O', 'X', 'X']
];
預期產量:
'XO..O.OXX'
解決方案:
board.flat().join('')
// "XO..O.OXX"
4. Array.prototype.flatMap
這部分很容易。假設有一個array A
,並且transformer
給出了一個函數。
A.flatMap(transformer)
定義爲A.map(transformer).flat()
。
首先,我們使用transformer
函數映射每個元素,然後展平數組。請注意,展平是在一個級別上。
關於命名的一句話。您可能想知道flatMap
如果我們使用map
first和flat
second 爲何調用此函數。爲什麼不呢mapFlat
?原因有很多。
首先,flatMap
是函數式編程中的衆所周知的功能。Lodash擁有RxJ和RxJ。
其次,請注意,鏈式表示法A.map(f).flat()
將一切顛倒了。如果我們只有函數而不是鏈式數組方法,則表達式將如下所示:flat(map(A, f))
。功能應用程序的這種自然順序由功能組成規則定義。
練習:假設您有一級方程式車隊的清單。
const teams = [
{ name: 'Ferrari', drivers: ['S.Vettel', 'C.Leclerc'] },
{ name: 'Mercedes', drivers: ['L.Hamilton', 'V.Bottas'] },
{ name: 'Red Bull', drivers: ['M.Verstappen', 'A.Albon'] },
{ name: 'McLaren', drivers: ['C.Sainz', 'L.Norris'] }
];
創建一個JavaScript表達式,該表達式以任何順序返回驅動程序數組。
解決方案:
我們可以創建一個循環並連接drivers
每個團隊的值。或者,我們也可以將每個團隊的價值映射到他們的驅動程序列表上(採摘),然後將其串聯起來。
teams.flatMap( team => team.drivers )
// ["S.Vettel", "C.Leclerc", "L.Hamilton", "V.Bottas",
// "M.Verstappen", "A.Albon", "C.Sainz", "L.Norris"]
5.可選的捕獲綁定
您多久編寫一次try
- catch
代碼段,而沒有使用catch塊提供的錯誤對象?
try {
// Parsing user input
} catch(e) {
console.warn('Invalid user input.');
}
我知道e
代碼中只是一個不必要的字符,但是創建和從未使用過變量看起來很令人不安。ES2019通過使錯誤對象綁定成爲可選選項來結束這個小問題:
try {
// Parsing user input
} catch {
console.warn('Invalid user input.');
}
6. Symbol.prototype.description
description
符號的屬性返回其描述。該描述是隻讀的。
const s1 = Symbol(),
s2 = Symbol('text');
console.log( s1.description )
> undefined
console.log( s2.description )
> 'text
在極少數情況下,您在對象中使用了符號鍵,並且想要在該鍵上打印調試或日誌記錄信息,那麼description屬性可能會派上用場。
爲了便於演示,建議使用字符串而不是符號。
即使不使用符號描述來確定兩個符號是否相同,這些描述仍可以在代碼中使用,因爲它們存儲了可選的字符串數據。
const s1 = Symbol('text'),
s2 = Symbol('text');
console.log( 's1 == s2', s1 == s2 );
> false
console.log(
's1.description == s2.description',
s1.description == s2.description
);
7. Function.prototype.toString
本節非常明顯,足以以查理·卓別林的風格進行說明。
Array.from.toString()
> "function from() { [native code] }"
(x => 2*x).toString()
> "x => 2*x"
var hello = function() {
console.log('hello');
}
hello.toString()
> "function() {
console.log('hello');
}"
用例:文檔,調試。
8.格式良好的JSON.stringify
這是您已經瞭解並欣賞的典型更新,或者根本不會打擾您。
請在tc39 / proposal-well-formed-stringify存儲庫中找到詳細信息。這樣做的目的是防止Unicode字符串出現格式錯誤。
9.穩定的Array.sort
對數組進行排序時,該數組的某些元素可能相等。這些相等元素的順序由排序算法保留。
這是另一種邊緣情況,可幫助您在基於不同的列(升序和降序)對錶進行排序時使渲染的毛刺稍微減少。
例:
const rows = [
{
name: 'Larry',
website: 'google.com',
topic: '42',
year: 1998
},
{
name: 'Zsolt',
website: 'devcareermastery.com',
topic: 'IT Career',
year: 2015
},
{
name: 'Zsolt',
website: 'zsoltnagy.eu',
topic: 'JavaScript',
year: 2015
}
];
假設兩個元素相等(即比較器返回零),則現在保證這些元素保持其原始順序:
rows.sort( ({name: first}, {name: second}) => {
if ( first > second ) return 1;
if ( first < second ) return -1;
return 0;
} );
這些年來保持不變:
rows.sort( (x, y) => x.year - y.year );
這是另一種極端情況,在極端情況下,可能會阻止您不穩定的行由應用程序呈現或由API返回。
10. JSON超集
除非您曾經擔心過,否則不要擔心。該規範可能值得一讀。
此更新主要是關於標準化和指定準確的定義,基於這些定義可以很好地描述和規範語言規範。
對於軟件工程師來說,這僅意味着在極少數情況下您遇到行分隔符('\u2028'
)或頁面分隔符('\u2029'
)的問題,請確保將它們統一視爲空格字符,就像空格,製表符或換行符一樣字符。