在本文中, 我将介绍通过 ES2018(ES9)引入的 JavaScript 的新功能, 以及它们的用途以及如何使用它们的示例.
JavaScript(ECMAScript)是一个不断发展的标准, 由多个平台上的许多供应商实现. ES6(ECMAScript 2015)是一个大型版本, 花了六年时间才完成. 新的年度发布流程已经制定, 以简化流程并更快地添加功能. ES9(ES2018)是撰写本文时的最新版本.
技术委员会 39(TC39)由包括浏览器供应商在内的各方组成, 他们在严格的推进路径上推动 JavaScript 提案:
Stage 0: strawman-- 最初想法的提交.
Stage 1: proposal(提案)-- 由 TC39 至少一名成员倡导的正式提案文件, 该文件包括 API 事例.
Stage 2: draft(草案)-- 功能规范的初始版本, 该版本包含功能规范的两个实验实现.
Stage 3: candidate(候选)-- 提案规范通过审查并从厂商那里收集反馈
Stage 4: finished(完成)-- 提案准备加入 ECMAScript, 但是到浏览器或者 Nodejs 中可能需要更长的时间
ES2016
ES2016 通过添加两个小功能证明了标准化过程:
数组包含() https://developer.mozilla.org/en-US/docs/web/JavaScript/Reference/Global_Objects/Array/includes 方法, 当数组中包含 https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/includes 值时返回 true 或 false, 以及
取幂 https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Arithmetic_Operators#Exponentiation_(**) 运算符, 与... 相同. a ** b https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Arithmetic_Operators#Exponentiation_(**) Math.pow(a, b)
ES2017
ES2017 提供了更多的新功能:
异步函数可实现更清晰的 Promise 语法
Object.values() 从包含名称 - 值对的对象中提取值数组
Object.entries(), 返回包含对象中名称和值的子数组数组
Object.getOwnPropertyDescriptors()
返回的对象限定为另一个对象的自己的属性属性描述符(.value,.writable,,,,)
.get``.set``.configurable``.enumerable
padStart()和, 字符串填充的两个元素 padEnd()
对象定义, 数组声明和函数参数列表的尾随逗号
SharedArrayBuffer 以及 Atomics 读取和写入共享内存位置(为响应 Spectre 漏洞而 https://meltdownattack.com/ 禁用).
有关更多信息, 请参阅 ES2017 中的新增功能 https://www.sitepoint.com/es2017-whats-new .
ES2018
ECMAScript 2018(或 ES9, 如果您更喜欢旧的表示法)现已推出. 以下功能已达到第 4 阶段, 但在编写本文时, 浏览器和运行时的工作实现将不完整.
异步迭代
在异步 / 等待过程中的某个时刻, 您将尝试在同步循环内调用异步函数. 例如:
- async function process(array) {
- for (let i of array) {
- await doSomething(i);
- }
- }
它不会起作用. 这也不会:
- async function process(array) {
- array.forEach(async i => {
- await doSomething(i);
- });
- }
循环本身保持同步, 并且总是在它们的内部异步操作之前完成.
ES2018 引入了异步迭代器, 它与常规迭代器一样, 只是方法返回一个 Promise. 因此, 关键字可以与循环一起使用以串行运行异步操作. 例如: next()awaitfor ... of
- async function process(array) {
- for await (let i of array) {
- doSomething(i);
- }
- }
- Promise.finally()
Promise 链可以成功并达到最终或失败并触发阻止. 在某些情况下, 无论结果如何, 您都希望运行相同的代码 - 例如, 清理, 删除对话框, 关闭数据库连接等..then().catch()
该 原型允许你指定一个地方的最终逻辑, 而不是在最后的复制它和:.finally().then().catch()
- function doSomething() {
- doSomething1()
- .then(doSomething2)
- .then(doSomething3)
- .catch(err => {
- console.log(err);
- })
- .finally(() => {
- // finish here!
- });
- }
Rest/Spread 属性
ES2015 引入了 Rest 参数 https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Functions/Rest_parameters 和扩展运算符 https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Operators/Spread_syntax . 三个点 (...) 仅用于数组. Rest 参数语法允许我们将一个布丁数量的参数表示为一个数组.
- restParam(1, 2, 3, 4, 5);
- function restParam(p1, p2, ...p3) {
- // p1 = 1
- // p2 = 2
- // p3 = [3, 4, 5]
- }
spread 运算符以相反的方式工作, 并将数组转换为可以传递给函数的单独参数. 例如, 给定任意数量的参数, 返回最高值: Math.max()
- const values = [99, 100, -1, 48, 16];
- console.log( Math.max(...values) ); // 100
ES2018 为对象解构提供了和数组一样的 Rest 参数 () 和展开操作符, 一个简单的例子:
- const myObject = {
- a: 1,
- b: 2,
- c: 3
- };
- const { a, ...x } = myObject;
- // a = 1
- // x = { b: 2, c: 3 }
或者您可以使用它将值传递给函数:
- restParam({
- a: 1,
- b: 2,
- c: 3
- });
- function restParam({ a, ...x }) {
- // a = 1
- // x = { b: 2, c: 3 }
- }
跟数组一样, Rest 参数只能在声明的结尾处使用. 此外, 它只适用于每个对象的顶层, 如果对象中潜逃对象则无法适用.
扩展运算符可以在其他对象内使用, 例如:
- const obj1 = { a: 1, b: 2, c: 3 };
- const obj2 = { ...obj1, z: 26 };
- // obj2 is { a: 1, b: 2, c: 3, z: 26 }
您可以使用 spread 运算符来克隆对象(), 但请注意, 您只能获得浅拷贝. 如果属性包含另一个对象, 则克隆将引用同一对象. obj2 = { ...obj1 };
正则表达式命名捕获组(Regular Expression Named Capture Groups)
JavaScript 正则表达式可以返回匹配对象 - 类似于数组的值, 包含匹配的字符串. 例如, 要以 YYYY-MM-DD 格式解析日期:
- const
- reDate = /([0-9]{4})-([0-9]{2})-([0-9]{2})/,
- match = reDate.exec('2018-04-30'),
- year = match[1], // 2018
- month = match[2], // 04
- day = match[3]; // 30
它很难阅读, 并且更改正则表达式也可能会更改匹配对象索引.
ES2018 允许在开始捕获括号后立即使用符号命名组. 例如:?
- const
- reDate = /(?<year>[0-9]{4})-(?<month>[0-9]{2})-(?<day>[0-9]{2})/,
- match = reDate.exec('2018-04-30'),
- year = match.groups.year, // 2018
- month = match.groups.month, // 04
- day = match.groups.day; // 30
任何未匹配的命名组都将其属性设置为 undefined.
命名捕获也可用于方法中. 例如, 将日期转换为美国 MM-DD-YYYY 格式: replace()
- const
- reDate = /(?<year>[0-9]{4})-(?<month>[0-9]{2})-(?<day>[0-9]{2})/,
- d = '2018-04-30',
- usDate = d.replace(reDate, '$<month>-$<day>-$<year>');
正则表达式反向断言(lookbehind)
JavaScript 目前支持正则表达式中的前瞻断言. 这意味着必须进行匹配但不捕获任何内容, 并且断言不包含在整个匹配的字符串中. 例如, 要从任何价格中捕获货币符号:
- const
- reLookahead = /\D(?=\d+)/,
- match = reLookahead.exec('$123.89');
- console.log( match[0] ); // $
ES2018 引入以相同方式工作但是匹配前面的反向断言(lookbehind), 这样我就可以忽略货币符号, 单纯的捕获价格的数字:
- const
- reLookbehind = /(?<=\D)\d+/,
- match = reLookbehind.exec('$123.89');
- console.log( match[0] ); // 123.89
以上是 肯定反向断言, 非数字 \ D 必须存在. 同样的, 还存在 否定反向断言, 表示一个值必须不存在, 例如:
- const
- reLookbehindNeg = /(?<!\D)\d+/,
- match = reLookbehind.exec('$123.89');
- console.log( match[0] ); // null
正则表达式 dotAll 模式
正则表达式中点. 匹配除回车外的任何单字符, 标记 s 改变这种行为, 允许行终止符的出现, 例如:
/hello.world/s.test('hello\nworld'); // true
正则表达式 Unicode 属性转义
到目前为止, 还无法在正则表达式中本机访问 Unicode 字符属性. ES2018 添加了 Unicode 属性转义 - 在表单和 - 中设置了 (unicode) 标志的正则表达式. 例如:\p{...}\P{...}u
- const reGreekSymbol = /\p{Script=Greek}/u;
- reGreekSymbol.test('π'); // true
模板文字调整
最后, 删除了与模板文字中的转义序列相关的所有语法限制.
之前,\u 开始一个 unicode 转义,\x 开始一个十六进制转义,\ 后跟一个数字开始一个八进制转义. 这使得创建特定的字符串变得不可能, 例如 Windows 文件路径 C:\uuu\xxx\111. 更多细节参考模板字符串 https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/template_strings .
这就是 ES2018, 但是 ES2019 的工作已经开始了. 你有什么特色想要明年看到吗?
译者参考
拉丁的传说
来源: https://www.cnblogs.com/yuanchenchun/p/9492063.html