写点什么

ECMAScript 2019(ES10) 新特性简介

发布于: 2021 年 05 月 04 日

简介

ES10 是 ECMA 协会在 2019 年 6 月发行的一个版本,因为是 ECMAScript 的第十个版本,所以也称为 ES10.

今天我们讲解一下 ES10 的新特性。

ES10 引入了 2 大特性和 4 个小的特性,我们接下来一一讲解。

Array 的新方法 flat 和 flatMap

在 ES10 中,给 Array 引入了两个新的方法,分别是 flat 和 flatMap。

先来看一下 flat。

我们看一下 Array<T>.prototype.flat() 的定义:

.flat(depth = 1): any[]
复制代码

flat 的作用是将 Array 中的 Array 中的内容取出来,放到最顶层 Array 中。我们可以传入一个 depth 参数,表示的是需要 flat 的 Array 层级。

举个例子:

> [ 1,2, [3,4], [[5,6]] ].flat(0) // no change[ 1, 2, [ 3, 4 ], [ [ 5, 6 ] ] ]
> [ 1,2, [3,4], [[5,6]] ].flat(1)[ 1, 2, 3, 4, [ 5, 6 ] ]
> [ 1,2, [3,4], [[5,6]] ].flat(2)[ 1, 2, 3, 4, 5, 6 ]
复制代码

当 depth=0 的时候,就表示不会对 Array 内置的 Array 进行 flat 操作。

我们再看一下 Array<T>.prototype.flatMap()的定义:

 .flatMap<U>(  callback: (value: T, index: number, array: T[]) => U|Array<U>,  thisValue?: any): U[]
复制代码

flatMap 是 map 和 flat 的结合,下面的两个操作是等价的:

arr.flatMap(func)arr.map(func).flat(1)
复制代码

我们看几个 flatMap 的例子:

> ['a', 'b', 'c'].flatMap(x => x)[ 'a', 'b', 'c' ]> ['a', 'b', 'c'].flatMap(x => [x])[ 'a', 'b', 'c' ]> ['a', 'b', 'c'].flatMap(x => [[x]])[ [ 'a' ], [ 'b' ], [ 'c' ] ]
> ['a', 'b', 'c'].flatMap((x, i) => new Array(i+1).fill(x))[ 'a', 'b', 'b', 'c', 'c', 'c' ]
复制代码

Object 的新方法 fromEntries

Object.fromEntries 的主要作用就是通过给定的[key,value],来创建新的 Object 对象。

var newObj =  Object.fromEntries([['foo',1], ['bar',2]]);console.log(newObj);{ foo: 1, bar: 2 }
复制代码

上面例子中,我们通过给定的两个 key-value 对,创建了新的 object 对象。

和 fromEntries 相反的方法,就是 Object.entries,用来遍历对象属性。

还是刚刚的例子,我们再调用一下 Object.entries 方法:

console.log(Object.entries(newObj));[ [ 'foo', 1 ], [ 'bar', 2 ] ]
复制代码

String 的新方法 trimStart 和 trimEnd

JS 中已经有了 trim 的方法,可以消除 String 前后的空格。

> '  abc  '.trim()'abc'
复制代码

但有时候可能需要消除前面或者后面的空格,ES10 引入了 trimStart 和 trimEnd 方法:

> '  abc  '.trimStart()'abc  '> '  abc  '.trimEnd()'  abc'
复制代码

注意,有些浏览器可能已经有了 trimLeft 和 trimRight 方法,在 EMCAScript 规范中,他们和 trimStart,trimEnd 是等价的。

可访问的 Symbol 的 description 属性

我们在创建 Symbol 的时候,可以传入一个 description 作为参数来构建 Symbol:

const sym = Symbol('www.flydean.com');
复制代码

在 ES10 之前,我们想要访问 Symbol 的 description 是这样做的:

console.log(String(sym));//Symbol(www.flydean.com)
复制代码

现在我们可以直接通过 description 属性来访问了:

console.log(sym.description);//www.flydean.com
复制代码

可忽略的 catch 参数

在传统的写法中,catch 是要接受一个 error 参数的:

try {  // ···} catch (error) {  // ···}
复制代码

但有时候我们已经知道这个异常是不重要的,或者说,我们想忽略掉这个异常,那么在 ES10 中,我们可以省略这个 error 参数:

try {  // ···} catch {  // ···}
复制代码

Array 的稳定排序

Array 有个 sort 功能,可以根据元素内容进行排序。

ES10 中引入了稳定排序的概念,也就是说如果排序的 key 是相同的,那么这些相同 key 的顺序在排序中是不会发生变化的。

举个例子:

const arr = [  { key: 'b', value: 1 },  { key: 'a', value: 2 },  { key: 'b', value: 3 },];
复制代码


arr.sort((x, y) => x.key.localeCompare(y.key, 'en-US'));
复制代码

我们根据 key 来进行排序,从而让 a,排在 b 前面,但是两个 key=b 的元素位置是不会变化的。

console.log(arr);[  { key: 'a', value: 2 },  { key: 'b', value: 1 },  { key: 'b', value: 3 }]
复制代码

JSON.stringify

JSON 是一个很方便的数据传输格式,它不像 XML 那么复杂,优点就是体积小,便于传输。

根据 RFC3629 的规范,在公共环境中传输 JSON,必须使用 UTF-8 进行编码。

JSON text exchanged between systems that are not part of a closedecosystem MUST be encoded using UTF-8 [RFC3629].

在讲 JSON.stringify 之前,我们先回顾一下 ES6 中的 Escape sequences。

ES6 中有三种 escape:

  1. Hex escape:16 进制 escape。转义的是 2 位的 16 进制。

  > '\x7A' === 'z'  true
复制代码
  1. Unicode escape:转义的是 4 位的 16 进制

 > '\u007A' === 'z'  true
复制代码
  1. Unicode code point escape:转义的是 1 位或者多位的 16 进制

  > '\u{7A}' === 'z'  true
复制代码

最后一个转义是在 ES6 中引入的。

unicode 字符集最后是要存储到文件或者内存里面的,直接存储的话,空间占用太大。那怎么存呢?使用固定的 1 个字节,2 个字节还是用变长的字节呢?于是我们根据编码方式的不同,分成了 UTF-8,UTF-16,UTF-32 等多种编码方式。

其中 UTF-8 是一种变长的编码方案,它使用 1-4 个字节来存储。UTF-16 使用 2 个或者 4 个字节来存储。

而 UTF-32 是使用 4 个字节来存储。这三种编码方式中,只有 UTF-8 是兼容 ASCII 的,这也是为什么国际上 UTF-8 编码方式比较通用的原因(毕竟计算机技术都是西方人搞出来的)。

我们知道在 Unicode 编码中,U+D800 到 U+DFFF 的这些字符是预留给 UTF-16 使用,如果我们输入的是这个范围内的字符的话,是无法被转换成为 UTF-8 格式的。

这就是原来的 JSON.stringify 可能出现的问题。

在 ES10 中,JSON.stringify 对于这些不可转换成 UTF-8 的字符,直接返回对应的 code unit escape sequences。

console.log(JSON.stringify('\u{D800}'));"\ud800"
复制代码

JSON 被归为 ECMAScript 的子集

在之前,JSON 不是 ECMAScript 的子集,从而导致有些可以在 JSON 中包含的字符,不能够在 ECMAScript 的字面量中出现,比如 U+2028 和 U+2029 :

const sourceCode = '"\u2028"';eval(sourceCode); // SyntaxError
JSON.parse(json); // OK
复制代码

这次改变之后,我们在编码的时候就不需要再去区分是 JSON 还是 ECMAScript 了。

Function 的 toString 方法

在 ES10 中,如果 Function 可以通过以 ECMAScript 源代码的方式表示的话,则 toString 会直接返回这个函数的代码:

> class C { foo() { /*hello*/ } }> C.prototype.foo.toString()'foo() { /*hello*/ }'
复制代码

如果是一些 native 的方法,比如底层 c 或者 c++实现的代码,则直接返回[native code]:

> Math.pow.toString()'function pow() { [native code] }'
复制代码

本文作者:flydean 程序那些事

本文链接:http://www.flydean.com/ecmascript-10/

本文来源:flydean 的博客

欢迎关注我的公众号:「程序那些事」最通俗的解读,最深刻的干货,最简洁的教程,众多你不知道的小技巧等你来发现!

发布于: 2021 年 05 月 04 日阅读数: 10
用户头像

关注公众号:程序那些事,更多精彩等着你! 2020.06.07 加入

最通俗的解读,最深刻的干货,最简洁的教程,众多你不知道的小技巧,尽在公众号:程序那些事!

评论

发布
暂无评论
ECMAScript 2019(ES10)新特性简介