最全的 ES 重点内容整理(下)

ES2020 ( ES11 )

1.  可选链操作符

● 在 JavaScript 的操作中, 我们经常会访问一些属性, 但是如果他的前置是未定义的呢 ? 是不是就会报错了呢

● 这个时候我们不确定他的前置是不是确实存在, 那么我们怎么办呢 ?

● 只能是任由他报错, 如果要做一些容错处理, 那么只能是 try catch 了, 但是这样的代码太难受了看起来

● 在 ES2020 中出现了一个新的运算符, 可选链运算符 ( ?. ), 帮我们解决了这个问题

● 意义 : 当前置是 undefined 的时候, 不在继续向后访问属性, 直接返回 undefined

const obj = {
    info: { a: 100, b: 200 }
}

// 正常访问没有问题
console.log(obj.info.a) // => 100

// 当我们访问一个没有的前置的时候
console.log(obj.desc.a) // => 报错

// 这个时候就可以使用可选链运算符来代替
// 如果 obj.desc 存在, 那么继续向后访问
// 如果 obj.desc 不存在, 那么不继续向后访问
console.log(obj.desc?.a) // => undefined

2.  空值运算符 ( ?? )

● 这是一个非常简单的操作符, 和 || 操作符差不多, 但是又不太一样

● 只有当运算符左侧是 null 或者 undefined 的时候, 才会返回右侧的操作数据, 否则就返回左侧的操作数据

|| 运算符

如果左侧为 假值 的时候, 就会返回右侧的数据

?? 运算符

只有左侧为 null 或 undefined 的时候, 才会返回右侧的数据

const r1 = false || '千锋大前端'
console.log(r1) // => 千锋大前端

const r2 = false ?? '千锋大前端'
console.log(r2) // => false

3.  类的私有变量

● 在 ES2020 中, 扩展了类的私有变量

● 当你创建一个类以后, 你可能希望这个类在不同位置使用, 但是你又不希望类里面的某个或者某些属性可以全局使用, 而只是在类内部使用

● 此时, 你可以在类里面定义该属性的时候使用一个 哈希符号

class Person {
    // 定义了一个私有变量, 这个数据只能在类内部使用
    #age = 18

    getAge () { console.log(this.#age) }
}

const p = new Person()
p.getAge()
console.log(p.#age) // => 18

4.  Promise 方法扩展 : Promise.allSettled()

● 当我们在使用多实例 promise 的时候, 特别是当这些 promise 实例之间还有互相依赖的关系的时候, 我们需要拿到每一个 promise 的结果

● 现在, ES2020 为我们提供可一个 allSettled 方法, 可以实现这个功能

const p1 = new Promise((resolve, reject) => {
    setTimeout(() => {
        resolve('成功')
    }, 1000)
})

const p2 = new Promise((resolve, reject) => {
    setTimeout(() => {
        reject('失败')
    }, 1000)
})

Promise.allSettled([ p1, p2 ]).then(res => {
    console.log(res)
})

/*
    [
        { status: 'fulfilled', value: '成功' },
        { status: 'rejected', reason: '失败' }
    ]
*/

5.  数据类型扩展 : bigInt

● 我们在 JS 的开发中, 一般不会涉及到非常大的数字, 以前我们也没有想过有一天我们也要涉及一些及其大的数字

● 但是当有一天我们真的遇到了, 发现我们没办法准确的把握这些数字了

● 因为 js 能处理的最大的数字就是 2 的 53 次方

● 来看下面一个例子

console.log(2 ** 53)  // => 9007199254740992
console.log(2 ** 53 + 1) // => 9007199254740992
console.log(2 ** 53 + 2) // => 9007199254740994
console.log(2 ** 53 + 3) // => 9007199254740994
console.log(2 ** 53 + 4) // => 9007199254740996

● 我们会发现, 对于一些过于大的数字, 把握的不是很准确了, 这就会导致我们的程序出现一些不可控的问题

● 在 ES2020 的语法规范中, 提出了一种新的数据结构, 叫做 bigInt 表示大整数, 专门用来处理过大的数字的问题

● 在书写的时候也是非常简单的, 只需要在数字的末尾加上一个 n, 那么该数据就表示是一个大整数类型

const num = 123456789123456789n

● 我们需要注意的就是, 大整数类型不能和其他数值类型进行运算

console.log(2n * 3) // => 报错
console.log(2n * 3n) // => 6n

● 此时我们再来看到之前的例子

console.log(2n ** 53n)  // => 9007199254740992n
console.log(2n ** 53n + 1n) // => 9007199254740993n
console.log(2n ** 53n + 2n) // => 9007199254740994n
console.log(2n ** 53n + 3n) // => 9007199254740995n
console.log(2n ** 53n + 4n) // => 9007199254740996n

6.  模块化扩展 : 动态导入

● 以前我们的模块化实现规范, 只能是前置导入, 不管一个外部文件, 我们需要用到多少东西, 也不管我们需要在什么时候使用, 那么都需要先完整导入进来再说

● ES2020 我们支持了动态导入环境, 尤其是我们结合了 async 和 awiat 语法以后, 变得简单了很多

● 语法: import( '地址' )

● 例子 :

○ utils.js

const add = (a, b) => a + b
export { add }

○ index.js

const fn = async () => {
    const utils = await import('utils.js')
    const res = utils.add(10. 20)
    console.log(res) // => 30
}

ES2021 ( ES12 )

1.  字符串扩展 : String.prototype.replaceAll()

● 语法 : 字符串.replaceAll( 换下字符, 换上字符 )

● 作用 : 将所有换下字符全部替换

const str = 'hello world'
const res = str.replaceAll('l', '*')
console.log(res) // => 'he**o wor*d'

2.  数值分隔符

● 在书写数值的时候, 可以以 下划线(_) 作为分隔符书写

● 目的就是为了看的时候更直观的看到数字的大小

const num = 10000000000

○ 这个数字是多少呢, 一亿 ? 十亿 ? 一百亿 ?

○ 好难一眼看出来

const num = 10_000_000_000

○ 现在呢, 是不是直观了好多

3.  逻辑运算符的赋值表达式

● 以前, 我们的赋值表达式其实有 += -= 之类的内容

● 现在只不过是在 ES2021 中, 将 逻辑运算符与赋值表达式合作了

a ||= b
a &&= b
a ??= b

● 简单解释一下工作原理

a ||= b

// 等价于 if (!a) a = b
// 当 a 为 假值 的时候, 把 b 的值赋值给 a
a &&= b

// 等价于 if (a) a = b
// 当 a 为 真值 的时候, 把 b 的值赋值给 a
a ??= b

// 等价于 a ?? (a = b)
// 当 a 的值不是 undefined 或者 null 的时候, 把 b 的值赋值给 a

4.  Promise 扩展 : Promise.any 方法

● 是 Promise 的全局静态方法之一, 可以同时放置多个 promise 实例并行执行

● 只要任何一个 promise 实例成功了, 那么就返回这个成功的值

● 如果所有的 promise 实例都失败了, 那么最终走入失败

const p1 = new Promise( (resolve, reject) => {
    setTimeout(() => {
        reject('first')
    }, 500)
} )

const p2 = new Promise( (resolve, reject) => {
    setTimeout(() => {
        resolve('second')
    }, 500)
} )


const p3 = new Promise( (resolve, reject) => {
    setTimeout(() => {
        resolve('third')
    }, 500)
} )

Promise
    .any( [ p1, p2, p3 ] )
    .then(res => console.log(' result :  ', res))
    .catch(err => console.log('失败了 : ', err))
// result : second

ES2022 ( ES13 )

1.  类的字段声明

● 以前, 我们在书写类的时候, 只能在构造器( constructor ) 内进行字段的声明

class Person {
    constructor () {
        this.name = '千锋大前端'
        this.age = 8
    }
}

const p = new Person()
console.log(p.name)
console.log(p.age)

● 在 ES2022 中, 我们可以直接在类中定义字段了, 消除了必须要在构造器内定义字段

class Person {
    name = '千锋大前端'
    age = 8
}

const p = new Person()
console.log(p.name)
console.log(p.age)

2.  await 运算符扩展

● 以前, 我们的 await 运算符必须书写在函数内, 并且函数还有有 async 关键字

● 现在, 在 ES2020 的语法规范中, await 关键字可以直接在全局使用了

function ajax() {
    return new Promise(() => {
        /* ... */
    })
}

await ajax()

3.  数组扩展 : Array.prototype.at() 方法

● 语法 : 数组.at( 索引 )

● 其实就是通过索引访问数组内某一个数据

● 但是比我们的 数组[索引] 更强大一些

const arr = [ 10, 20, 30, 40 ]

// 以前:
console.log(arr[1]) // => 20
// 现在:
console.log(arr.at(1)) // => 20

// 以前:
console.log(arr[arr.length - 2]) // => 30
// 现在:
console.log(arr.at(-2)) // => 30

4.  数组扩展 : Array.prototype.findLast()和findLastIndex()

● 其实和之前的 find() 和 findIndex() 方法用法一样

● 只不过是从数组的末尾开始向前检索

const arr = [
    { value: 'x', id: 1 },
    { value: 'y', id: 2 },
    { value: 'z', id: 3 },
    { value: 'y', id: 4 },
    { value: 'x', id: 5 }
]

const r1 = arr.find( item => item.value === 'x' )
console.log(r1) // => {value: 'x', id: 1}

const r2 = arr.findLast( item => item.value === 'x' )
console.log(r2) // => {value: 'x', id: 5}

const r3 = arr.findIndex( item => item.value === 'x' )
console.log(r3) // => 0

const r4 = arr.findLastIndex( item => item.value === 'x' )
console.log(r4) // => 4

5.  正则扩展 : 匹配索引

● 以前, 我们在正则匹配的时候, 只能拿到符合要求的字符串片段的开始索引

● 现在, 在 ES2022 的语法规范中, 我们可以给正则添加一个 d 修饰符, 来获取到符合要求的字符串片段的开始索引和结束索引

// 以前 :
const str = '你好, 我是千锋大前端, 我今年 8 岁了'
const reg = /千锋大前端/
const res = reg.exec(str)
console.log(res)

/*
    0: "千锋大前端",
    groups: undefined,
    index: 6,
    input: "你好, 我是千锋大前端, 我今年 8 岁了",
    length: 1
*/
// 现在 :
const str = '你好, 我是千锋大前端, 我今年 8 岁了'
const reg = /千锋大前端/d
const res = reg.exec(str)
console.log(res)

/*
    0: "千锋大前端",
    groups: undefined,
    index: 6,
    indices: [ [ 6, 11 ], groups: undefined ],
    input: "你好, 我是千锋大前端, 我今年 8 岁了",
    length: 1
*/

● 我们可以同时拿到这一段字符串的开始索引和结束索引, 分别是 [6] 和 [11]

ES2023 ( ES14 )

1.  数组方法扩展 : toReversed() 和 toSorted() 和 toSpliced()

● 他们的使用方法和语法于原先的 reverse() sort() splice() 是一样的

● 只不过, 原先的方法会直接在原始数组上操作

● ES2023 扩展的几个方法, 不会改变原始数组, 而是以返回值的形式返回改变后的数组

● 以 toReversed() 为例 :

const arr = [ 10, 20, 30, 40 ]

const res = arr.reverse()
console.log('原始数组 : ', arr) // => [ 40, 30, 20, 10 ]
console.log('返回值 : ', res) // => [ 40, 30, 20, 10 ]
const arr = [ 10, 20, 30, 40 ]

const res = arr.toReversed()
console.log('原始数组 : ', arr) // => [ 10, 20, 30, 40 ]
console.log('返回值 : ', res) // => [ 40, 30, 20, 10 ]

● 其他的方法和 toReversed() 方法是一个道理

2.  其他

● ES2023 还在计划引入一些新的内容

管道操作符

Record

tuple

lteration Helpers

Better Intl Support

● 只不过目前还处在计划中

● 等到彻底发布了, 浏览器也可以支持了, 我会再次更新, 给大家分享最新的技术点

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值