尝鲜ECMAScript2022(ES13)

256 阅读3分钟

前言:最近,听到大佬们说ES13出了新特新,本菜鸡也来尝尝鲜部分新特性

image.png

一.at 方法

1.1 说明

数组和字符串等都有该方法

1.2 功能:

用来做通过索引查询的,比如 arr[0] 这是数组的第一个元素,那么查询最后一个,我们原来通常会 arr[arr.length-1],现在可以直接 arr.at[-1],当然你也可以使用-2等等。

1.3 使用:

let arr = [1, 2, 3, 4, 5]
console.log(arr.at(-1)) // 5
console.log(arr.at(-2)) // 4
console.log(arr.at(-3)) // 3
...
console.log(arr.at(-5)) // 1

 
let str = 'abc'
console.log(str.at(-1)) // c

// 打印结果可以知道数组、字符串有 at 方法 数字没有
console.log(new Array(), new String(), new Number())

image.png

image.png

image.png

二、Top-level await(顶层 await)

在ES2017中,正式引入了 async/await,以简化 Promise 的使用,但是 await 关键字只能在 async 函数内使用。如果在异步函数之外使用 await 就会报错。

顶层 await 允许我们在 async 函数外使用 await 关键字。它允许模块充当大型异步函数,通过顶层 await,这些模块可以等待资源加载,这样其他导入这些模块的模块在执行代码之前要等待资源加载完才会去执行。

之前由于 await 仅在 async 函数中使用,因此模块需通过将代码包装在 async 函数来在代码中包含await:

在测试顶层await 建议用一些环境测试(要不然可能出现不支持的情况),比如我这里使用vite + vue3来测试。

  • 先配置环境
npm init @vitejs/app demo
  • src/test.js
let users;

export const fetchUsers = async () => {
    const res = await fetch('http://testapi.xuexiluxian.cn/api/slider/getSliders');
    users = res.json();
}
fetchUsers();

export { users };
  • src/App.vue
<script setup> 
import { users } from './test.js';
console.log('1', users);
console.log('2'); 
</script>

这样会有一个缺点,直接导入的 users 会是 undefined。如果我们需要访问得到它,需要在异步执行完成之后:

<script setup>
import {users} from "./test";

console.log('1', users)// 直接访问,undefined

setTimeout(() => {
  console.log('2', users) //等待异步执行完成, 在进行访问
}, 500)

console.log('3')
</script>

image.png

当然,这种方法并不完全实现,因为如果异步函数执行花费的时间超过500毫秒,它就不会起作用了,users 仍然是 undefined。

而 top-level await(顶层 await)可以解决这些问题:

// src/test.js
let users;

export const fetchUsers = async () => {
    // 使用顶层 await
    const res = await fetch('http://testapi.xuexiluxian.cn/api/slider/getSliders');
    users = res.json();
}
fetchUsers();

// src/App.vue
import {users} from "./test";

console.log('1', users)
console.log('3')

此时的 users 必须等到异步执行完毕才会访问。

三、class

3.1 公共属性和方法

在 ES13 之前,在定义类的属性时,需要在构造函数中定义了实例字段和绑定方法

class Person {
    constructor() {
        this.name = 'mint'
    }

    writeCode() {
        console.log('写代码..')
    }
}

ES13 可以使用公共实例字段,这样就简化了类的定义,使代码更加简洁可读

class Person {
    name = 'mint'
    writeCode() {
        console.log('写代码..')
    }
}

3.2 在属性或者方法前加上 # 就就可了

class Person {
    ...
    
    #sex = '男'
}

const p = new Person()
console.log(p.#sex);

//sex 是私有属性,外面不可以修改和获取到的

image.png

直接报错了

可以打印对象看到,但是不可以修改和访问到

class Person {
    #sex = '男'

    name = 'mint'
    writeCode() {
        console.log('写代码..')
    }
}

const p = new Person()
// console.log(p.name);
// console.log(p.writeCode());
// console.log(p.#sex);

console.log(p);

image.png

私有方法也是一样的道理

class Person {
    #sex = '男'
    #name = 'mint'
    #writeCode() {
        console.log('写代码..')
    }
}

3.3 静态公共字段、静态私有字段、静态私有方法

class Person {
    // 静态公共字段
    static str = '你好鸭~'
    // 静态私有字段
    static #count = 1
    // 静态私有方法
    static #setCount = () => {
    // 实例化之后, this 不在指向 Person, 所有需要改成 Person 类调用
        Person.#count += 1
    }
    newSetCount = () => {
        // 实例化之后,this 不再指向 Person,所有需要改成 Person 类调用
        Person.#setCount()
    }
}

const p = new Person()

console.log(Person.str); // 你好鸭~
console.log(p.str);      // undefined

四.参考

2022 年 6 月 22 日,第 123 届 ECMA 大会批准了 ECMAScript 2022 语言规范。可以参考:262.ecma-international.org/13.0/