本章按时间倒序列出了 ES2016-ES2022 的新特性。它从 ES2015 (ES6) 之后开始,因为该版本有太多特性无法在此列出。
ES2022 可能会在 2022 年 6 月成为标准。以下提案已达到第 4 阶段,并计划成为该标准的一部分
类的新的成员
私有槽检查(“私有字段的人体工程学品牌检查”):以下表达式检查 obj
是否具有私有槽 #privateSlot
in obj #privateSlot
模块中的顶级 await
:我们现在可以在模块的顶层使用 await
,而不必再进入异步函数或方法。
error.cause
:Error
及其子类现在允许我们指定哪个错误导致了当前错误
new Error('Something went wrong', {cause: otherError})
可索引值的 .at()
方法 允许我们读取给定索引处的元素(如括号运算符 []
),并支持负索引(与括号运算符不同)。
> ['a', 'b', 'c'].at(0)'a'
> ['a', 'b', 'c'].at(-1)'c'
以下“可索引”类型具有 .at()
方法
字符串
数组
Uint8Array
等。RegExp 匹配索引:如果我们向正则表达式添加一个标志,则使用它会生成匹配对象,该对象记录每个组捕获的开始和结束索引。
Object.hasOwn(obj, propKey)
提供了一种安全的方法来检查对象 obj
是否具有键为 propKey
的自有属性。与 Object.prototype.hasOwnProperty
相比,它适用于所有对象。
ES2022 中可能还会添加更多特性
如果发生这种情况,本书将相应更新。
ECMAScript 2021 中添加了以下特性
String.prototype.replaceAll()
允许我们替换正则表达式或字符串的所有匹配项(.replace()
仅替换字符串的第一次出现)
> 'abbbaab'.replaceAll('b', 'x')'axxxaax'
Promise.any()
和 AggregateError
:Promise.any()
返回一个 Promise,一旦 Promises 可迭代对象中的第一个 Promise 被 fulfilled,该 Promise 就会被 fulfilled。如果只有 rejection,它们将被放入 AggregateError
中,该错误将成为 rejection 值。
当我们只对几个 Promise 中第一个被 fulfilled 的 Promise 感兴趣时,我们使用 Promise.any()
。
||= b
a &&= b
a ??= b a
下划线 (_
) 作为分隔符
123_456.789_012
6_000_000_000_000_000_000_000_000n
弱引用:此特性超出了本书的范围。有关它的更多信息,请参阅其提案。
ECMAScript 2020 中添加了以下特性
新的模块特性
通过 import()
进行动态导入:普通的 import
语句是静态的:我们只能在模块的顶层使用它,并且它的模块说明符是一个固定的字符串。import()
改变了这一点。它可以在任何地方使用(包括条件语句),我们可以计算它的参数。
import.meta
包含当前模块的元数据。它第一个得到广泛支持的属性是 import.meta.url
,它包含一个字符串,其中包含当前模块文件的 URL。
命名空间重新导出:以下表达式在命名空间对象 ns
中导入模块 'mod'
的所有导出,并导出该对象。
export * as ns from 'mod';
属性访问和方法调用的可选链。可选链的一个例子是
.?prop value
如果 value
是 undefined
或 null
,则此表达式计算结果为 undefined
。否则,它计算结果为 value.prop
。当某些属性可能丢失时,此特性在属性读取链中特别有用。
?? defaultValue value
如果 value
是 undefined
或 null
,则此表达式为 defaultValue
,否则为 value
。此运算符允许我们在缺少某些内容时使用默认值。
以前在这种情况下使用逻辑或运算符 (||
),但它在这里有缺点,因为它在左侧为假时返回默认值(这并不总是正确的)。
BigInt - 任意精度整数:BigInt 是一种新的原始类型。它支持可以任意大的整数(它们的存储空间根据需要增长)。
String.prototype.matchAll()
:如果未设置标志 /g
,则此方法会抛出异常,并返回一个包含给定字符串的所有匹配对象的迭代器。
Promise.allSettled()
接收一个 Promises 的迭代器。一旦所有输入的 Promise 都 settled,它就会返回一个 fulfilled 的 Promise。fulfilled 值是一个数组,每个输入的 Promise 对应一个对象,可以是以下两种之一
{ status: 'fulfilled', value: «fulfilled 值» }
{ status: 'rejected', reason: «rejected 值» }
globalThis
提供了一种访问全局对象的方法,该方法在浏览器和服务器端平台(如 Node.js 和 Deno)上均可使用。
for-in
机制:此特性超出了本书的范围。有关它的更多信息,请参阅其提案。
ECMAScript 2019 中添加了以下特性
数组方法 .flatMap()
的工作原理类似于 .map()
,但它允许回调返回零个或多个值的数组,而不是单个值。然后将返回的数组连接起来,成为 .flatMap()
的结果。用例包括
数组方法 .flat()
将嵌套数组转换为扁平数组。我们可以选择告诉它在哪个嵌套深度停止扁平化。
Object.fromEntries()
从一个对 *entries* 进行迭代的迭代器创建一个对象。每个 entry 都是一个包含属性键和属性值的二元素数组。
字符串方法:.trimStart()
和 .trimEnd()
的工作原理类似于 .trim()
,但仅删除字符串开头或结尾的空格。
可选的 catch
绑定:如果我们不使用 catch
子句的参数,现在可以省略它。
Symbol.prototype.description
是一个用于读取符号描述的 getter。以前,描述包含在 .toString()
的结果中,但不能单独访问。
以下新的 ES2019 特性超出了本书的范围
JSON.stringify()
:请参阅2ality 博客文章。Function.prototype.toString()
修订版:请参阅2ality 博客文章。ECMAScript 2018 中添加了以下特性
异步迭代 是同步迭代的异步版本。它基于 Promises
await
才能访问项目。for-of
循环。使用异步迭代器,我们使用 for-await-of
循环。将扩展运算符用于对象字面量:通过在对象字面量中使用扩展运算符 (...
),我们可以将另一个对象的属性复制到当前对象中。用例之一是创建对象 obj
的浅拷贝
const shallowCopy = {...obj};
剩余属性(解构):在对值进行对象解构时,我们现在可以使用剩余语法 (...
) 获取对象中所有先前未提及的属性。
const {a, ...remaining} = {a: 1, b: 2, c: 3};
.deepEqual(remaining, {b: 2, c: 3}); assert
Promise.prototype.finally()
与 try-catch-finally 语句的 finally
子句相关 - 类似于 Promise 方法 .then()
与 try
子句相关,.catch()
与 catch
子句相关。
换句话说:无论 Promise 是 fulfilled 还是 rejected,都会执行 .finally()
的回调。
新的正则表达式特性
RegExp
命名捕获组:除了按编号访问组之外,我们现在还可以命名它们并按名称访问它们
const matchObj = '---756---'.match(/(?<digits>[0-9]+)/)
.equal(matchObj.groups.digits, '756'); assert
RegExp
后视断言 补充了前视断言
(?<=X)
如果当前位置前面是 'X'
则匹配。(?<!X)
如果当前位置前面不是 '(?<!X)'
则匹配。正则表达式的 s
(dotAll
) 标志。如果此标志处于活动状态,则点匹配行终止符(默认情况下不匹配)。
RegExp
Unicode 属性转义 使我们在匹配 Unicode 代码点集时拥有更强大的功能 - 例如
> /^\p{Lowercase_Letter}+$/u.test('aüπ')true
> /^\p{White_Space}+$/u.test('\n \t')true
> /^\p{Script=Greek}+$/u.test('ΩΔΨ')true
模板字面量修订版 允许在标记模板中使用带有反斜杠的文本,这在字符串字面量中是非法的 - 例如
windowsPath`C:\uuu\xxx\111`
latex`\unicode`
ECMAScript 2017 中添加了以下特性
异步函数 (async/await
) 允许我们使用同步外观的语法编写异步代码。
Object.values()
返回一个数组,其中包含给定对象的所有可枚举字符串键属性的值。
Object.entries()
返回一个数组,其中包含给定对象的所有可枚举字符串键属性的键值对。每对都编码为一个二元素数组。
字符串填充:字符串方法 .padStart()
和 .padEnd()
插入填充文本,直到接收方足够长
> '7'.padStart(3, '0')'007'
> 'yes'.padEnd(6, '!')'yes!!!'
函数参数列表和调用中的尾随逗号:自 ES3 以来,数组字面量中就允许使用尾随逗号,自 ES5 以来,对象字面量中也允许使用尾随逗号。现在,函数调用和方法调用中也允许使用它们。
以下两个特性超出了本书的范围
Object.getOwnPropertyDescriptors()
(请参阅“深入 JavaScript”)ECMAScript 2016 中添加了以下特性
Array.prototype.includes()
检查数组是否包含给定值。
> 4 ** 216
ECMAScript 功能列表取自 TC39 已完成提案页面。