最全的 ES 重点内容整理(下)"/>
最全的 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 = 18getAge () { 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) // => 0const 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
● 只不过目前还处在计划中
● 等到彻底发布了, 浏览器也可以支持了, 我会再次更新, 给大家分享最新的技术点
更多推荐
最全的 ES 重点内容整理(下)
发布评论