JavaScript进阶(二十六):ES各版本特性详解_es版本

  1. 循环等待
    在异步函数中,有时需要在同步 for 循环中使用异步(非同步)函数。
async function process(array) {
  for (const i of array) {
    await doSomething(i);
  }
}

async function process(array) {
  array.forEach(async i => {
    await doSomething(i);
  });
}

上面的代码不会像预期的那样输出期望的结果。

for循环本身还是同步的,会在循环中的异步函数完成之前执行整个for循环,然后将里面的异步函数逐一执行。

ES9 增加了异步迭代器,允许 awaitfor 循环一起使用,逐步执行异步操作。

async function process(array) {
  for await (const i of array) {
    doSomething(i);
  }
}

  1. promise.finally()
    无论是成功(.then())还是失败(.catch()),Promise 后面都会执行的部分。
  2. Rest, Spread
    在 ES2015 中,Rest 不定长度参数…,可以转换成数组传入。
  3. 正则表达式组
    RegExp 可以返回匹配的数据包
const regExpDate = /([0-9]{4})-([0-9]{2})-([0-9]{2})/;
const match      = regExpDate.exec('2020-06-25');
const year       = match[1]; // 2020
const month      = match[2]; // 06
const day        = match[3]; // 25

  1. 正则表达式 dotAll
    . 表示匹配除输入以外的任何符号,添加这些标志后,允许匹配输入。
/hello.world/.test('hello\nworld');  // false
/hello.world/s.test('hello\nworld'); // true

六、ES10 (ES2019)

  1. 更友好的 JSON.stringify
    如果输入是 Unicode 但超出范围,则 JSON.stringify 最初会返回格式错误的 Unicode 字符串。

现在是第 3 阶段的提案,使其成为有效的 Unicode 并以 UTF-8 呈现。

  1. Array.prototype.flat() & Array.prototype.flatMap()
    展平阵列
  2. String.prototype.trimStart() & String.prototype.trimEnd()
    trimStart() 方法从字符串的开头删除空格,trimLeft() 是此方法的别名。
  3. Object.fromEntries()
    Object.fromEntries() 方法将键值对列表转换为对象。
  4. String.prototype.matchAll
    matchAll() 方法返回将字符串与正则表达式匹配的所有结果的迭代器,包括捕获组。
  5. fixed catch 绑定
    在使用catch之前,不管有用与否,一定要传入一个eparameter来表示接收到的错误。
    如果现在不用,可以省略。
  6. BigInt(新数字类型)(重要)
    BigInt 值,有时也称为 BigInt,是一个 bigint 原语,通过将 n 附加到整数文字的末尾,或通过调用 BigInt() 函数(没有 new 运算符)并给它一个整数值或字符串来创建值。
  • ES5:String, Number, Boolean, Null, Undefined
  • ES6 新增:Symbol,到ES6就一共有6 种类型
  • ES10 新增:BigInt,就达到 7 种类型

七、ES11 (ES2020)

  1. Promise.allSettled()
    Promise.allSettled() 方法返回一个在所有给定的 Promise 都已实现或拒绝后实现的 Promise,并带有一组对象,每个对象都描述了每个 Promise 的结果。

它通常用于当有多个不依赖于彼此成功完成的异步任务,或者总是想知道每个 Promise 的结果时。

相比之下,Promise.all() 返回的 Promise 可能更合适,如果任务相互依赖/如果想立即拒绝其中任何一个拒绝。

  1. 可选链操作符?.

在开发中,很容易遇到先判断数据是否存在,判断是否写入。

const isUserExist = user && user.info;
if (isUserExist) { 
    username = user.info.name; 
}

如果返回的数据为null或者用户对象下没有相应属性,则会抛出Uncaught TypeError: Cannot read property...

导致程序无法继续执行

使用 ?.,语法更简单

const username = user?.info?.name;

如果存在,获取name的值,如果不存在,赋值undefined

|| 一起使用,只需一行!

const username = user?.name || 'guest';

  1. Nullish 合并运算符 ??
    JavaScript中,遇到0、nullundefined时会自动转为false
    但有时0其实是一个正常的值,只能容错undefinednull,但是使用??,可以保持简洁。
  2. Dynamic-import
    从字面上看,应该很容易理解,就是在需要的时候加载相关的逻辑。
  3. GlobalThis
    全局 globalThis 属性包含全局 this 值,类似于全局对象。

八、ES12 (ES2021)

  1. Promise.any()
    Promise.any() 接受一个可迭代的 Promise 对象。它返回一个单一的 Promise,只要 iterable 中的任何一个 Promise 完成,就会返回一个 Promise,并带有已完成的 Promise 的值。

如果可迭代的实现中没有任何承诺(如果所有给定的承诺都被拒绝),则返回的承诺会被 AggregateError 拒绝,AggregateErrorError 的一个新子类,它将单个错误组合在一起。

  1. 逻辑赋值运算符
    在开发过程中,可以使用 ES2020 中提出的逻辑运算符 ||&& 和 `??(Nullish coalescing operator)来解决一些问题。

而 ES2021 会提出 ||= , &&= , ??= ,概念类似于 +=

let b = 2
b += 1 
// equal to b = b + 1
let a = null
a ||= 'some random text'  // a become to'some random text'
// equal a = a || 'some random text'
let c = 'some random texts'
c &&= null  // c become to null
// equal to c = c && null
let d = null
d ??= false  // d become to false
// equal to d = d ?? false

  1. WeakRef
    WeakRef 对象包含对对象的弱引用,该对象称为其目标或引用对象。对对象的弱引用是不会阻止对象被垃圾收集器回收的引用。相反,普通(或强)引用将对象保存在内存中,当一个对象不再有任何强引用时,JavaScript 引擎的垃圾收集器可能会销毁该对象并回收其内存。如果发生这种情况,将无法再从弱引用中获取对象。

九、ES13 (ES2022)

ES13 带来了 6 个新特性:

  • 模块顶层作用域支持 await 表达式。
  • 新增私有类元素(#)、静态块;in 操作符支持私有类元素。
  • 正则新增 d 标志和其对应的 hasIndices 属性,提供了获取捕获组开始索引和结束索引的方法。
  • Error 实例增加 cause 属性,可携带更多错误信息。
  • StringsArraysTypedArrays 新增 at 方法,支持关联访问。
  • Object.hasOwn 代替 Object.prototype.hasOwnProperty,判断对象是否含有属性。
9.1 Strings、Arrays、TypedArrays 的 at 方法

利用下标访问数组元素时,下标会被转换为字符串,负数下标也对应着一个独立的数组元素,所以 Js 的数组是不支持关联访问的。ES13 新增了 at 方法,可以利用负数索引进行关联访问,例如以下示例,可以利用 at 方法和负数索引 -2 来访问倒数第二个元素。

const array = [5, 12, 8, 130, 44];

array.at(-2); // 130

9.2 私有类元素

在类的定义中,以 “#” 开头的标识符为私有标识符,由私有标识符定义的类元素被称为私有类元素,私有类元素只能在类中才能被访问到。类的属性、静态属性、方法、静态方法、访问器、静态访问器都可以被定义为私有类元素。示例代码如下:

class ClassA {
    // 私有属性
    #privateProperty;

    // 静态私有属性
    static #privateStaticProperty;

    // 静态私有 Getter
    static get #privateStaticGet() {
        return 'private-static-get';
    }

    // 静态私有 Setter
    static set #privateStaticSet(val) {
    }

    // 静态私有方法
    static #privateStaticMethod() {
        return 'private-static-method'
    }

    constructor(propertyValue) {
        // 初始化私有属性
        this.#privateProperty = propertyValue;
    }

    // 私有 Get
    get #privateGet() {
        return 'private-get'
    }

    // 私有 Set
    set #privateSet() {
    }

    // 私有方法
    #privateMethod() {
        return 'private-method'
    }
}


在类的内部可以正常访问私有类元素,在类的外部访问私有类元素会抛出句法错误。

class ClassA {
    // 私有属性
    #privateProperty;

    constructor(property, privateProperty) {
        this.property = property;
        this.#privateProperty = privateProperty;
    }

    // 在方法中访问私有属性
    getPrivateProperty() {
        return this.#privateProperty;
    }
}

const instance = new ClassA('property', 'private-property');

instance.property; // 'property'
instance.#privateProperty; // Uncaught SyntaxError: Private field '#privateProperty' must be declared in an enclosing class
instance.getPrivateProperty(); // 'private-property'

以上就是私有类元素的用法,它有效隔离了类内外的数据和逻辑,进一步增强了封装的效果,使程序更加健壮。

9.3 静态块

静态块提供了更加灵活的静态类元素初始化渠道,可以在静态块中使用一系列的语句来完成静态类元素的初始化。可以利用 this 在静态块中访问类的其他静态属性(包括私有属性)。

class ClassA {
    // 静态属性
    static staticProperty;

    // 静态块初始化静态属性,捕捉错误
    static {
        try {
            this.staticProperty = getStaticProperty();
        } catch {
            console.log('Error');
        }
    }
}

当一个类具有多个静态块时,它们会按照定义的顺序进行执行。

class ClassA {
    // 静态属性 A
    static staticPropertyA;

    // 静态块 A
    static {
        this.staticPropertyA = 'static-block-a';
        console.log('static-block-a');
    }

    // 静态属性 B
    static staticPropertyB;

    // 静态块 B
    static {
        this.staticPropertyB - 'static-block-b';
        console.log('static-block-b');
    }
}

// 输出
// static-block-a
// static-block-b

当一个类具有父类时,会先执行父类的静态块,再执行子类的静态块。可以利用 super 在子类的静态块中访问父类的属性。

最后

开源分享:【大厂前端面试题解析+核心总结学习笔记+真实项目实战+最新讲解视频】

给大家分享一些关于HTML的面试题。


console.log('static-block-b');
}

}

// 输出
// static-block-a
// static-block-b


当一个类具有父类时,会先执行父类的静态块,再执行子类的静态块。可以利用 `super` 在子类的静态块中访问父类的属性。



### 最后

**[开源分享:【大厂前端面试题解析+核心总结学习笔记+真实项目实战+最新讲解视频】](https://bbs.csdn.net/topics/618166371)**

**给大家分享一些关于HTML的面试题。**

[外链图片转存中...(img-l2yN2BMB-1714301043507)]
[外链图片转存中...(img-EAO73hvi-1714301043508)]



  • 20
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值