【笔记】State Of Js2022中的ES语言特性
Jan 15, 2023jses6State Of Js 2022 中的 ES 语言特性
报告地址:https://2022.stateofjs.com/en-US/
Proxies
用于创建一个对象的代理,从而实现基本操作的拦截和自定义(如属性查找、赋值、枚举、函数调用等)。
Proxy 现在还是挺常用的,比如 Vue3、和 Reflect 配合使用元编程
1 | const handler = { |
趋势
趋势有点奇怪,2021 年及之前了解人数/使用人数比例还在逐年上升,2022 年居然有所减少。
Promise.allSettled()
Promise.allSettled()
方法以 promise 组成的可迭代对象作为输入,并且返回一个 Promise 实例。当输入的所有 promise 都已敲定时(包括传递空的可迭代类型),返回的 promise 将兑现,并带有描述每个 promsie 结果的对象数组。
看起来感觉跟Promise.all()
很像,但Promise.allSettled()
的最大不同点在于Promise.allSettled()
永远不会被 reject。
在使用 Promise.all()
时,如果有一个 promise 出现了异常,被 reject 了,就不会走到.then
,如:
1 | const promises = [Promise.resolve(1), Promise.resolve(2), Promise.reject(3)]; |
这种情况下,Promise.all()
的关键问题在于:尽管能用 catch
捕获其中的异常,但你会发现其他执行成功的 promise 的消息都丢失了。
而Promise.allSettled
不一样:
1 | const promises = [Promise.resolve(1), Promise.resolve(2), Promise.reject(3)]; |
可以看到所有 promise 的数据都被包含在 then
语句中,且每个 promise 的返回值多了一个 status
字段
兼容性
polyfill:
1 | if (Promise && !Promise.allSettled) { |
趋势
总体来看这几年使用有所上升
Dynamic Import
关键字 import
可以像调用函数一样来动态的导入模块。以这种方式调用,将返回一个 promise。
1 | import('/modules/my-module.js').then(module => { |
这种使用方式也支持 await
关键字。
1 | const module = await import('/modules/my-module.js'); |
兼容性
趋势
Private Fields
类属性在默认情况下是公有的,但可以使用增加哈希前缀 #
的方法来定义私有类字段,这一隐秘封装的类特性由 js 自身强制执行。如:
1 | class ClassWithPrivateField { |
从作用域之外引用 #
名称、内部在未声明的情况下引用私有字段、或尝试使用 delete 移除声明的字段都会抛出语法错误。如:
1 | class ClassWithPrivateField { |
并且类似于公有字段,私有字段在构造(construction)基类或调用子类的 super()
方法时被添加到类实例中。
私有实例方法
1 | class ClassWithPrivateMethod { |
兼容性
私有性还是比较好做 polyfill 的,比如:
1 | class Test { |
babel:
1 | function _classPrivateFieldInitSpec(obj, privateMap, value) { |
趋势
逐渐上升。
Nullish Coalescing
空值合并运算符(??
)是一个逻辑运算符,当左侧的操作数为 null
或者 undefined
时,返回其右侧操作数,否则返回左侧操作数。
与逻辑或运算符(||
)不同,逻辑或运算符会在左侧操作数为假值时返回右侧操作数。也就是说,如果使用 ||
来为某些变量设置默认值,可能会遇到意料之外的行为。比如为假值(例如,''
或 0
)时。见下面的例子。
1 | const foo = null ?? 'default string'; |
兼容性
兼容处理也很简单,polyfill 如:
1 | function getNum(num) { |
babel:
1 | function getNum(num) { |
趋势
还算是在上升。
Numeric Separators
增强数字可读性的分隔符_
。
1 | 1_000_000_000_000; |
兼容性
babel 处理时去掉分隔符就好了。
趋势
有所上升。
String.prototype.replaceAll()
1 | const p = 'The quick brown fox jumps over the lazy dog. If the dog reacted, was it really lazy?'; |
兼容性
Corejs 的 polyfill 可见https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/es.string.replace-all.js
趋势
有所上升。
String.prototype.matchAll()
1 | const regexp = /t(e)(st(\d?))/g; |
兼容性
Corejs 的 polyfill 可见https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/es.string.match-all.js
趋势
有所上升。
Logical Assignment
- Logical OR assignment:
(x ||= y)
- Logical AND assignment:
(x &&= y)
如:
1 | let a = 1; |
1 | let x = 0; |
兼容性
趋势
有所上升。
Promise.any()
Promise.any()
接收一个由 Promise 所组成的可迭代对象,该方法会返回一个新的 promise,一旦可迭代对象内的任意一个 promise 变成了兑现状态,那么由该方法所返回的 promise 就会变成兑现状态,并且它的兑现值就是可迭代对象内的首先兑现的 promise 的兑现值。如果可迭代对象内的 promise 最终都没有兑现(即所有 promise 都被拒绝了),那么该方法所返回的 promise 就会变成拒绝状态,并且它的拒因会是一个 AggregateError
实例,这是 Error
的子类,用于把单一的错误集合在一起。
1 | const promise1 = Promise.reject(0); |
返回值
- 如果传入了一个空的可迭代对象,那么就会返回一个已经被拒的 promise
- 如果传入了一个不含有 promise 的可迭代对象,那么就会返回一个异步兑现的 promise
- 其余情况下都会返回一个处于等待状态的 promise。如果可迭代对象中的任意一个 promise 兑现了,那么这个处于等待状态的 promise 就会异步地(调用栈为空时)切换至兑现状态。如果可迭代对象中的所有 promise 都被拒绝了,那么这个处于等待状态的 promise 就会异步地切换至被拒状态。
兼容性
Corejs 的 polyfill 可见https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/es.promise.any.js
趋势
居然有所降低。
Array.prototype.at()
at()
方法接收一个整数值并返回该索引对应的元素,允许正数和负数。负整数从数组中的最后一个元素开始倒数。
1 | const array1 = [5, 12, 8, 130, 44]; |
参数: index
, {String}
- 要返回的数组元素的索引(位置)。当传递负数时,支持从数组末端开始的相对索引;也就是说,如果使用负数,返回的元素将从数组的末端开始倒数。
返回值
- 匹配给定索引的数组中的元素。如果找不到指定的索引,则返回
undefined
。
兼容性
Corejs 的 polyfill 可见https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/es.array.at.js
趋势
呈上升趋势。
Top Level await()
在模块的顶层,你可以单独使用关键字 await
(异步函数的外面)。也就是说一个模块如果包含用了 await
的子模块,该模块就会等待该子模块,这一过程并不会阻塞其它子模块。
下面是一个在 export
表达式中使用了 Fetch API
的例子。任何文件只要导入这个模块,后面的代码就会等待,直到 fetch
完成。
1 | // fetch request |
兼容性
趋势
呈上升趋势。
Temporal
一个新的日期/时间 API,具体使用https://tc39.es/proposal-temporal/docs/index.html
1 | console.log('Initialization complete', Temporal.Now.instant()); |
兼容性
不兼容
趋势
新 APi,也没呈现出趋势
Array.prototype.findLast()
findLast()
方法返回数组中满足提供的测试函数条件的最后一个元素的值。如果没有找到对应元素,则返回 undefined
。
1 | const inventory = [ |
兼容性
Corejs 的 polyfill 可见https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/es.array.find-last.js
趋势
Error.prototype.cause
导致一个错误的数据属性实例表明错误的具体的原始致因。
使用它当捕获和抛出收到一个错误更具体的或有用的错误信息仍然为了获得最初的错误。
1 | try { |
兼容性
趋势
Object.hasOwn()
Object.hasOwn()
用来代替 Object.prototype.hasOwnProperty()
.
1 | const object1 = { |
兼容性
Corejs 的 polyfill 可见https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/es.object.has-own.js
趋势
Regexp Match Indices
1 | const regex1 = new RegExp('foo', 'd'); |
1 | const str1 = 'foo bar foo'; |
兼容性
趋势
å
Author
My name is Micheal Wayne and this is my blog.
I am a front-end software engineer.
Contact: michealwayne@163.com