ECMA 2018(es9)新特性

本章内容:

1.异步迭代

async/await的某些时刻,你可能尝试在同步循环中调用异步函数。例如:

js 复制代码
async function process(array) {
  for (let i of array) {
    await doSomething(i);
  }
}

这段代码不会正常运行,下面这段同样也不会:

js 复制代码
async function process(array) {
  array.forEach(async (i) => {
    await doSomething(i);
  });
}

这段代码中,循环本身依旧保持同步,并在在内部异步函数之前全部调用完成。

ES2018 引入异步迭代器(asynchronous iterators),这就像常规迭代器,除了next()方法返回一个 Promise。因此await可以和for...of循环一起使用,以串行的方式运行异步操作。例如:

js 复制代码
async function process(array) {
  for await (let i of array) {
    doSomething(i);
  }
}

2.Promise.finally()

一个 Promise 调用链要么成功到达最后一个.then(),要么失败触发.catch()。在某些情况下,你想要在无论 Promise 运行成功还是失败,运行相同的代码,例如清除,删除对话,关闭数据库连接等。

.finally()允许你指定最终的逻辑:

js 复制代码
function doSomething() {
  doSomething1()
    .then(doSomething2)
    .then(doSomething3)
    .catch((err) => {
      console.log(err);
    })
    .finally(() => {
      // finish here!
    });
}

3.Rest/Spread 属性

ES2015 引入了Rest 参数扩展运算符。三个点(...)仅用于数组。Rest 参数语法允许我们将一个不定数量的参数表示为一个数组。

js 复制代码
restParam(1, 2, 3, 4, 5);

function restParam(p1, p2, ...p3) {
  // p1 = 1
  // p2 = 2
  // p3 = [3, 4, 5]
}

展开操作符以相反的方式工作,将数组转换成可传递给函数的单独参数。例如Math.max()返回给定数字中的最大值:

js 复制代码
const values = [99, 100, -1, 48, 16];
console.log(Math.max(...values)); // 100

ES2018 为对象解构提供了和数组一样的 Rest 参数()和展开操作符,一个简单的例子:

js 复制代码
const myObject = {
  a: 1,
  b: 2,
  c: 3,
};

const { a, ...x } = myObject;
// a = 1
// x = { b: 2, c: 3 }

或者你可以使用它给函数传递参数:

js 复制代码
restParam({
  a: 1,
  b: 2,
  c: 3,
});

function restParam({ a, ...x }) {
  // a = 1
  // x = { b: 2, c: 3 }
}

跟数组一样,Rest 参数只能在声明的结尾处使用。此外,它只适用于每个对象的顶层,如果对象中嵌套对象则无法适用。

扩展运算符可以在其他对象内使用,例如:

js 复制代码
const obj1 = { a: 1, b: 2, c: 3 };
const obj2 = { ...obj1, z: 26 };
// obj2 is { a: 1, b: 2, c: 3, z: 26 }

可以使用扩展运算符拷贝一个对象,像是这样obj2 = {...obj1},但是 这只是一个对象的浅拷贝。另外,如果一个对象 A 的属性是对象 B,那么在克隆后的对象 cloneB 中,该属性指向对象 B。

4.正则表达式命名捕获组

JavaScript 正则表达式可以返回一个匹配的对象------一个包含匹配字符串的类数组,例如:以YYYY-MM-DD的格式解析日期:

js 复制代码
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 允许命名捕获组使用符号?<name>,在打开捕获括号(后立即命名,示例如下:

js 复制代码
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

命名捕获也可以使用在replace()方法中。例如将日期转换为美国的 MM-DD-YYYY 格式:

js 复制代码
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>");

5.正则表达式反向断言

目前 JavaScript 在正则表达式中支持先行断言(lookahead)。这意味着匹配会发生,但不会有任何捕获,并且断言没有包含在整个匹配字段中。例如从价格中捕获货币符号:

js 复制代码
const reLookahead = /\D(?=\d+)/,
  match = reLookahead.exec("$123.89");

console.log(match[0]); // $

ES2018 引入以相同方式工作但是匹配前面的反向断言(lookbehind),这样我就可以忽略货币符号,单纯的捕获价格的数字:

js 复制代码
const reLookbehind = /(?<=\D)\d+/,
  match = reLookbehind.exec("$123.89");
console.log(match[0]); // 123.89

以上是 肯定反向断言 ,非数字\D必须存在。同样的,还存在 否定反向断言,表示一个值必须不存在,例如:

js 复制代码
const reLookbehindNeg = /(?<!\D)\d+/,
  match = reLookbehind.exec("$123.89");
console.log(match[0]); // null

6.正则表达式 dotAll 模式

正则表达式中点.匹配除回车外的任何单字符,标记s改变这种行为,允许行终止符的出现,例如:

js 复制代码
/hello.world/.test("hello\nworld"); // false
/hello.world/s.test("hello\nworld"); // true

7.正则表达式 Unicode 转义

到目前为止,在正则表达式中本地访问 Unicode 字符属性是不被允许的。ES2018 添加了 Unicode 属性转义------形式为\p{...}\P{...},在正则表达式中使用标记 u (unicode) 设置,在\p块儿内,可以以键值对的方式设置需要匹配的属性而非具体内容。例如:

js 复制代码
const reGreekSymbol = /\p{Script=Greek}/u;
reGreekSymbol.test("π"); // true

此特性可以避免使用特定 Unicode 区间来进行内容类型判断,提升可读性和可维护性。

8.非转义序列的模板字符串

之前,\u开始一个 unicode 转义,\x开始一个十六进制转义,\后跟一个数字开始一个八进制转义。这使得创建特定的字符串变得不可能,例如 Windows 文件路径 C:\uuu\xxx\111。更多细节参考模板字符串

相关推荐
zhougl9961 小时前
html处理Base文件流
linux·前端·html
花花鱼1 小时前
node-modules-inspector 可视化node_modules
前端·javascript·vue.js
HBR666_2 小时前
marked库(高效将 Markdown 转换为 HTML 的利器)
前端·markdown
careybobo3 小时前
海康摄像头通过Web插件进行预览播放和控制
前端
TDengine (老段)3 小时前
TDengine 中的关联查询
大数据·javascript·网络·物联网·时序数据库·tdengine·iotdb
杉之4 小时前
常见前端GET请求以及对应的Spring后端接收接口写法
java·前端·后端·spring·vue
喝拿铁写前端5 小时前
字段聚类,到底有什么用?——从系统混乱到结构认知的第一步
前端
再学一点就睡5 小时前
大文件上传之切片上传以及开发全流程之前端篇
前端·javascript
木木黄木木6 小时前
html5炫酷图片悬停效果实现详解
前端·html·html5
请来次降维打击!!!6 小时前
优选算法系列(5.位运算)
java·前端·c++·算法