翻译:李冰 原文:http://www.zsoltnagy.eu/whats-new-in-es2019/
ES2019或ES10是JavaScript的2019版本。在2015年进行重大更新之后,JavaScript每年都在发展。开发人员可以获得一小组有用的功能,这些功能可以帮助我们在创新与稳定性之间取得平衡。
您也可以在此博客中了解JavaScript的发展,因为第一篇文章发布于2015年。现在是时候从实际角度考察ES2019更新。像往常一样,不要期望对理论上的极端情况进行冗长的描述。本文宁愿加倍讨论实际用例。
如果您想查看每个JavaScript版本的完整更新列表,请查看此兼容性表。当我在最新的Google Chrome浏览器中查看更新时,我发现即使对于建议的ES2020版本,大多数测试也已通过。
请注意,您的代码可能必须支持多个浏览器。因此,请考虑在您的应用程序中使用polyfills。
让我们一一探索ES2019功能列表:
回想一下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 = `
String trimming
`;
在早期版本的JavaScript中,已经可以进行修整:
template.trim()
// "String trimming
"
在ES2019中,也可以只修剪字符串的左侧或右侧。
trimStart
并且trimLeft
在我们必须将文本(包括末尾的空格)插入特定位置时非常方便。trimEnd
并且trimRight
在我们必须在文本结尾之后插入一些内容时非常方便(例如,在= $0
突出显示控制台中DOM元素的标记之前显示HTML标记)。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"
这部分很容易。假设有一个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.');
}
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
);
本节非常明显,足以以查理·卓别林的风格进行说明。
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');
}"
用例:文档,调试。
这是您已经了解并欣赏的典型更新,或者根本不会打扰您。
请在tc39 / proposal-well-formed-stringify存储库中找到详细信息。这样做的目的是防止Unicode字符串出现格式错误。
对数组进行排序时,该数组的某些元素可能相等。这些相等元素的顺序由排序算法保留。
这是另一种边缘情况,可帮助您在基于不同的列(升序和降序)对表进行排序时使渲染的毛刺稍微减少。
例:
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返回。
除非您曾经担心过,否则不要担心。该规范可能值得一读。
此更新主要是关于标准化和指定准确的定义,基于这些定义可以很好地描述和规范语言规范。
对于软件工程师来说,这仅意味着在极少数情况下您遇到行分隔符('\u2028'
)或页面分隔符('\u2029'
)的问题,请确保将它们统一视为空格字符,就像空格,制表符或换行符一样字符。