JavaScript 不断演变,每次迭代都会得到一些新的内部更新。让我们来看看 ES2019 有哪些新的特性,加入到我们日常开发中。
可选的 catch 参数
在进行 try catch 错误处理过程中,你如果没有给 catch 传参数的话,代码就会报错。在 es2019 中,你可以选择性地不给它传入参数。一个比较常见的使用场景是: 在使用 JSON.parse 解析字符串的时候,虽然你知道可能会报错,但是你并不关心这个错误,这时候你就可以把错误参数吞掉。
// 原先的代码可能长这样:
try {
// do something
} catch (e) {
console.log(e);
}
// 新的代码
try {
// do something
} catch {
// do other thing without error parameter
}
虽然新的语言规范提供了吞掉错误参数的机制,不过个人建议在实际代码中还是要看情况选择性地使用。
JSON.superset 超集
之前如果 JSON 字符串中包含有行分隔符 (\u2028) 和段落分隔符 (\u2029),那么在解析过程中会报错:SyntaxError: Invalid or unexpected token。es2019 中新增了对它们的支持。
Symbol.prototype.description
description 是一个只读属性,它会返回 Symbol 对象的可选描述的字符串,用来代替 toString() 方法。
const symbol = Symbol("Desc");
symbol.description; // "Desc"
symbol.toString(); // "Symbol(Desc)"
Function.toString()
现在,我们对一个函数调用 toString(),将完全按照定义的方式返回函数,包括空格和注释。之前我们有:
function /* foo comment */ foo() {}
foo.toString(); // "function foo() {}"
// 新
foo.toString(); // "function /* foo comment */ foo() {}"
Object.fromEntries
这是一个全新的方法:根据提供的键值对生成对象。它是我们熟悉的函数 Object.Entries 的逆向操作。(Object.Entries 将对象转换为数组,以便更容易地进行操作。)在转换之后,我们会得到一个数组,但是现在我们可以将调整过后的数组返回到一个对象中。让我们试着用一个例子,我们想平方所有对象属性的值:
const obj = { prop1: 2, prop2: 10, prop3: 15 };
let array = Object.entries(obj); // [["prop1", 2], ["prop2", 10], ["prop3", 15]]
让我们用一个简单的映射将新生成的键值对的值平方:
array = array.map(([key, value]) => [key, Math.pow(value, 2)]); // [["prop1", 4], ["prop2", 100], ["prop3", 225]]
我们已经转换了对象值,但我们只剩下一个数组,这时候我们就需要 Object.fromEntries,它将数组转换回一个对象:
const newObj = Object.fromEntries(array); // {prop1: 4, prop2: 100, prop3: 225}
修复 JSON.stringify 问题
修复了一些 unicode 字符显示的问题
// Non-BMP characters still serialize to surrogate pairs.
JSON.stringify("?");
// → '"?"'
JSON.stringify("\uD834\uDF06");
// → '"?"'
// Unpaired surrogate code units will serialize to escape sequences.
JSON.stringify("\uDF06\uD834");
// → '"\\udf06\\ud834"'
JSON.stringify("\uDEAD");
// → '"\\udead"'
String.trimStart() 和 String.trimEnd()
除了同时删除字符串两边的空格的 String.Trim()之外,现在还出现了另一个方法只删除字符串两边任意一边的空格:
const str = " hello ";
str.trim(); // "hello";
str.trimStart(); // "hello ";
str.trimEnd(); // " hello";
Array.prototype.{flat,flatMap}
将数组打平这个功能在实际开发当中一直有着比较高的出场率,但是可惜之前官方并没有为我们提供这个 API,所以我们一般都是通过 lodash 等工具库或者自己手动实现这个方法函数。 我们先来回顾一下,之前如果要用原生的 es5 或 es6,我们应该如何快速简单地实现这个方法呢? 大家可以参考以下这段代码:
function flatten(a) {
return Array.isArray(a) ? [].concat(...a.map(flatten)) : [a];
}
在 es2019 当中,官方为我们提供了这样一个类似的 API:flat。原理大体上和上面的代码一样,内部实现都是采用了递归的 concat 方法。 不过在默认的情况下,es2019 中这个 flat 方法只会打平第 1 层数据。所以如果我们想要支持多层递归的话,就需要显式给它传入参数。
[1, 2, 3, [1, 2, [3, [4]]]].flat(2); // [1, 2, 3, 1, 2, 3, [4]]
另一个和它一起提供的是 flatMap 方法,其实就相当于 flat 和 map 一起组合操作。
[1, 3, 5].map((x) => [x * x]); // [[1],[9],[25]]
[1, 3, 5].flatMap((x) => [x * x]); // [1,9,25]