本章内容:

  • 行分隔符(U + 2028)和段分隔符(U + 2029)符号现在允许在字符串文字中,与 JSON 匹配
  • 更加友好的 JSON.stringify
  • 新增了 Array 的flat()方法和flatMap()方法
  • 新增了 String 的trimStart()方法和trimEnd()方法
  • Object.fromEntries()
  • Symbol.prototype.description
  • Function.prototype.toString()现在返回精确字符,包括空格和注释
  • 简化try {} catch {},修改 catch 绑定
  • Legacy RegEx
  • 私有的实例方法和访问器

1.行分隔符(U + 2028)和段分隔符(U + 2029)符号现在允许在字符串文字中,与 JSON 匹配

以前,这些符号在字符串文字中被视为行终止符,因此使用它们会导致 SyntaxError 异常。

2.更加友好的 JSON.stringify

如果输入 Unicode 格式但是超出范围的字符,在原先 JSON.stringify 返回格式错误的 Unicode 字符串。现在实现了一个改变 JSON.stringify 的第 3 阶段提案,因此它为其输出转义序列,使其成为有效 Unicode(并以 UTF-8 表示)

3.新增 Array 的flat()方法和flatMap()方法

flat()flatMap()本质上就是是归纳(reduce) 与 合并(concat)的操作。

Array.prototype.flat()

flat() 方法会按照一个可指定的深度递归遍历数组,并将所有元素与遍历到的子数组中的元素合并为一个新数组返回。

flat()方法最基本的作用就是数组降维

var arr1 = [1, 2, [3, 4]];
arr1.flat();
// [1, 2, 3, 4]

var arr2 = [1, 2, [3, 4, [5, 6]]];
arr2.flat();
// [1, 2, 3, 4, [5, 6]]

var arr3 = [1, 2, [3, 4, [5, 6]]];
arr3.flat(2);
// [1, 2, 3, 4, 5, 6]

//使用 Infinity 作为深度,展开任意深度的嵌套数组
arr3.flat(Infinity);
// [1, 2, 3, 4, 5, 6]
  • 其次,还可以利用flat()方法的特性来去除数组的空项
var arr4 = [1, 2, , 4, 5];
arr4.flat(); // [1, 2, 4, 5]

Array.prototype.flatMap()

flatMap() 方法首先使用映射函数映射每个元素,然后将结果压缩成一个新数组。它与 map 和 深度值 1 的 flat 几乎相同,但 flatMap 通常在合并成一种方法的效率稍微高一些。 这里我们拿 map 方法与 flatMap 方法做一个比较。

var arr1 = [1, 2, 3, 4];

arr1.map((x) => [x * 2]);
// [[2], [4], [6], [8]]

arr1.flatMap((x) => [x * 2]);
// [2, 4, 6, 8]

// 只会将 flatMap 中的函数返回的数组 “压平” 一层
arr1.flatMap((x) => [[x * 2]]);
// [[2], [4], [6], [8]]

4.String 的trimStart()方法和trimEnd()方法

新增的这两个方法很好理解,分别去除字符串首尾空白字符,这里就不用例子说声明了。

5.Object.fromEntries()

Object.entries()方法的作用是返回一个给定对象自身可枚举属性的键值对数组,其排列与使用 for...in 循环遍历该对象时返回的顺序一致(区别在于 for-in 循环也枚举原型链中的属性)。

Object.fromEntries() 则是 Object.entries() 的反转。

Object.fromEntries() 函数传入一个键值对的列表,并返回一个带有这些键值对的新对象。这个迭代参数应该是一个能够实现@iterator 方法的的对象,返回一个迭代器对象。它生成一个具有两个元素的类似数组的对象,第一个元素是将用作属性键的值,第二个元素是与该属性键关联的值。

  • 通过 Object.fromEntries, 可以将 Map 转化为 Object:
const map = new Map([
  ["foo", "bar"],
  ["baz", 42],
]);
const obj = Object.fromEntries(map);
console.log(obj); // { foo: "bar", baz: 42 }
  • 通过 Object.fromEntries, 可以将 Array 转化为 Object:
const arr = [
  ["0", "a"],
  ["1", "b"],
  ["2", "c"],
];
const obj = Object.fromEntries(arr);
console.log(obj); // { 0: "a", 1: "b", 2: "c" }

6.Symbol.prototype.description

通过工厂函数 Symbol()创建符号时,您可以选择通过参数提供字符串作为描述:

const sym = Symbol("The description");

以前,访问描述的唯一方法是将符号转换为字符串:

assert.equal(String(sym), "Symbol(The description)");

现在引入了 getter Symbol.prototype.description 以直接访问描述:

assert.equal(sym.description, "The description");

Function.prototype.toString()

现在返回精确字符(源代码),包括空格和注释

function /* comment */ foo /* another comment */() {}
// 之前不会打印注释部分
console.log(foo.toString()); // function foo(){}
// ES2019 会把注释一同打印
console.log(foo.toString()); // function /* comment */ foo /* another comment */ (){}
// 箭头函数
const bar /* comment */ = /* another comment */ () => {};
console.log(bar.toString()); // () => {}

修改 catch 绑定

在 ES10 之前,我们必须通过语法为 catch 子句绑定异常变量,无论是否有必要。很多时候 catch 块是多余的。 ES10 提案使我们能够简单的把变量省略掉。

不算大的改动。

之前是:

try {
  // do sth
} catch (e) {
  // do sth
}

现在是:

try {
  // do sth
} catch {
  // do sth
}