当前位置:   article > 正文

ES新特性系列(三)—— ES9、ES10

ES新特性系列(三)—— ES9、ES10

        前面两篇咱们已经了解了ES6—ES8的常用新特性:
        ES新特性系列(一)—— ES的简介与ES6

        ES新特性系列(二)—— ES7、ES8

        有兴趣的彦祖们可以跳转了解。本期咱们接着聊ES9、ES10的新特性。

                                                

一、ES9(ECMAScript 2018)常用新特性

1.异步迭代(Asynchronous Iteration)

        异步迭代的出现主要是为了解决异步数据流的处理问题。

        传统Javascript中的for...of...循环只能处理同步的数据结构,我们看下面这个简单的例子:

  1. const promises = [Promise.resolve('data1'), Promise.resolve('data2'), Promise.resolve('data3')];
  2. for (let promise of promises) {
  3. console.log(promise);
  4. }
  5. // 输出结果
  6. // Promise {<fulfilled>: 'data1'}
  7. // Promise {<fulfilled>: 'data2'}
  8. // Promise {<fulfilled>: 'data3'}

       因为上述代码是同步执行,所以输出结果是立即输出,并且输出Promise的结果,而直接就是Promise本身,这显然不是咱们想要的结果。这时候咱们就要看ES9引入的异步迭代: for await...of 循环了。

        异步迭代允许我们以同步的编程方式来处理异步的数据。这大大简化了异步编程,并使得代码更易读和理解。同样以上述例子来看看异步迭代处理的结果:

  1. const promises = [Promise.resolve('data1'), Promise.resolve('data2'), Promise.resolve('data3')];
  2. // 使用 for await...of 循环
  3. async function processPromises() {
  4. for await (let result of promises) {
  5. console.log(result);
  6. }
  7. }
  8. processPromises(); // 结果:data1、data2、data3,您可以复制代码在控制台试一下

         await关键词允许我们在循环之前等待异步操作得出结果,再进行处理,项目中合理使用异步迭代可以大大提高咱们的代码简洁和可读性。

2.Promise.prototype.finally()

         这个特性大家在项目中应该都经常使用,它的作用相当于给Promise的所有操作做“收尾”的工作,通常用于在 Promise 完成(无论是 fulfilled 还是 rejected)后执行某些操作。

         举个简单的例子:如果你给一个提交按钮设置了loading——在提交数据到结果返回之前按钮都是在loading状态,当结果返回时,无论是提交成功还是处理失败,都需要取消按钮的loading状态才行,此时我们就需要用到 .finally() :

  1. submit(data) { // 确认
  2. this.loading = true
  3. method(data).then(res => {
  4. console.log(res.code)
  5. }).finally(() => {
  6. this.loading = false
  7. })
  8. }
 3.Rest/Spread 属性

          咱们初学的话可以将它看作是拓展运算符升级版,回忆一下ES6的拓展运算符——它允许在数组中操作,而此时升级后的拓展运算符,它允许我们在对象中对进行操作。

1.Spread 属性:Spread 操作符在对象中的应用,可以用于从一个对象创建一个新对象,同时添加、覆盖或组合属性。例如:

  1. const obj1 = { a: 1, b: 2, c: 4 };
  2. const obj2 = { ...obj1, c: 3 };
  3. const obj3 = { c: 3, ...obj1 };
  4. console.log(obj2) // { a: 1, b: 2, c: 3 }
  5. console.log(obj3) // { c: 4, a: 1, b: 2 } 你注意到差别了吗?

2.Rest 属性:Rest 操作符在对象中的应用,可以用于从一个对象中提取出剩余的属性到一个新的对象中。例如:

  1. const obj = { a: 1, b: 2, c: 3 };
  2. const { a, ...rest } = obj; // rest: { b: 2, c: 3 }
4. 命名捕获组(Named Capture Groups)

        这个特性主要是正则表达式上的升级:在这之前,我们只能使用数字索引(如 match[1])来访问捕获组。但是,当正则表达式变得复杂,或者你修改了捕获组的顺序,使用数字索引就会变得困难和混乱。例如:

  1. let re = /(\d{4})-(\d{2})-(\d{2})/;
  2. let match = re.exec('2022-01-01');
  3. let year = match[1]; // "2022"
  4. let month = match[2]; // "01"
  5. let day = match[3]; // "01"

       然后我们可能有项目需要要调整时间格式:

  1. let re = /(\d{2})-(\d{2})-(\d{4})/;
  2. let match = re.exec('01-01-2022');
  3. let month = match[1]; // "01"
  4. let day = match[2]; // "01"
  5. let year = match[3]; // "2022"

       这时我们发现输出的month、year、day顺序完全不对了。有的彦祖说我一个一个手动再把索引改了不就得了,但是如果是100个数据呢?如果是项目全局需要改呢?这样傻傻改索引很麻烦且容易出错。接下来咱们用命名捕获组来解决该问题:

  1. let re = /(?<month>\d{2})-(?<day>\d{2})-(?<year>\d{4})/;
  2. let match = re.exec('01-01-2022');
  3. let year = match.groups.year; // "2022"
  4. let month = match.groups.month; // "01"
  5. let day = match.groups.day; // "01"

      在这个例子中,(?<year>\d{4})、(?<month>\d{2}) (?<day>\d{2}) 是命名捕获组。?<year>、?<month> ?<day> 是捕获组的名称,而 \d{4}、\d{2} 和 \d{2} 是捕获组的模式。在执行匹配后,你可以通过 match.groups.year、match.groups.month match.groups.day 来访问捕获组的值。

      由此,无论上面的正则中的顺序如何修改,我们下面的year、month、day都可以准确的获取到对应的值,大大降低了我们对代码的维护成本,并且可读性强。

二、ES10(ECMAScript 2019)常用新特性

1.对象方法:Object.fromEntries()

      还记得咱们再上一篇ES8的特性中讲到过Object.entries()的方法吗?它可以返回对象键值对的二维数组:

  1. const obj = {a: 1, b: 2, c: 3}
  2. console.log(Object.entries(obj)); // 输出:[['a', 1], ['b', 2], ['c', 3]]

     Object.fromEntries()就是Object.entries()的反向操作:它可以将一个二维的键值对数组转化为对象:

  1. const arr = [['a', 1], ['b', 2], ['c', 3]]
  2. console.log(Object.fromEntries(arr)) // {a: 1, b: 2, c: 3}
2.数组方法:Array.prototype.flat() 和 Array.prototype.flatMap()

     两个都是数组扁平化的方法,​flat() 方法用于将嵌套的数组“拉平”。

  1. const arr = [1, [2, [3, [4]], 5]];
  2. console.log(arr.flat()); // [1, 2,[3,[4]], 5]
  3. console.log(arr.flat(2)); // [1, 2,3,[4], 5]
  4. console.log(arr.flat(Infinity)); // [1, 2, 3, 4, 5]

      Array.prototype.flat() 可以输入参数,默认为1。(其中的Infinity相当于一个全局的无穷数)。

     flatMap() flat()map()合起来的方法:先执行map操作,然后再对结果进行flat()操作:

  1. const arr = [1, 2, 3, 4];
  2. const result = arr.flatMap(x => [x, x * 2]);
  3. console.log(result); // 输出: [1, 2, 2, 4, 3, 6, 4, 8]
3.String.prototype.trimStart() 和 String.prototype.trimEnd()

      这两个方法用于去除字符串开始和结束处的空白字符。

  1. const str = ' foo ';
  2. console.log(str.trimStart()); // "foo "
  3. console.log(str.trimEnd()); // " foo"
4.新的基本数据类型 BigInt

       之前,JavaScript 中的所有数字都是 Number 类型,这种类型只能安全地表示 -(2^53 - 1) 到 2^53 - 1 范围内的整数。超出这个范围,Number 类型将无法精确表示整数。但是BigInt可以解决,不过项目中应该也不会太常用,了解即可:

  1. // 使用 BigInt 字面量创建 BigInt
  2. const a = 1234567890123456789012345678901234567890n;
  3. // 使用 BigInt 函数创建 BigInt
  4. const b = BigInt("1234567890123456789012345678901234567890");
  5. console.log(a === b); // 输出:true
  6. // BigInt 还支持常见的算数运算
  7. const c = a + b;
  8. console.log(c); // 输出:2469135780246913578024691357802469135780n
5.可选的 catch 绑定

       在之前的 ECMAScript 版本中,catch 子句必须包含一个异常变量。而在 ES10 中,如果你不需要访问这个异常变量,你可以省略它。

  1. try {
  2. throw 'error';
  3. } catch {
  4. console.log('An error occurred');
  5. }
6.Function.prototype.toString() 的更新

       在 ES10 中,Function.prototype.toString() 方法返回的结果现在包含函数的注释。

  1. function exampleFunction() {
  2. // 这是一个示例函数
  3. console.log('Hello, world!');
  4. }
  5. console.log(exampleFunction.toString());
  6. // 输出为
  7. "function exampleFunction() {
  8. // 这是一个示例函数
  9. console.log('Hello, world!');
  10. }"
7.全局对象globalThis

        一个新的全局对象,不论当前代码在何处运行,都可以用它来访问全局对象。

  1. globalThis.myGlobalVariable = 'Hello, world!';
  2. console.log(myGlobalVariable); // 输出:'Hello, world!'

       在这个例子中,myGlobalVariable 是一个全局变量,可以在任何地方访问,无论是在函数内部,还是在模块中。

8.Symbol.prototype.description

   它提供了一种获取 Symbol 描述的方法。

  1. let mySymbol = Symbol('my description');
  2. console.log(mySymbol.description); // 输出 "my description"

三、总结

       本期ES9、ES10的常用新特性就给大家介绍到这里了,如果大家觉得不错,就请点赞关注一下吧。后续将继续为大家带来前端相关的内容,如有疑问,可以评论回复。

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/很楠不爱3/article/detail/558105
推荐阅读
相关标签
  

闽ICP备14008679号