2023 年 7 月 11 日 - 7 月 13 日,进展第 97 次 TC39 会议在挪威举行,汇总下面就来看看在这次会议中哪些 ECMAScript 提案取得了新进展吧!最新
TC39 是一个推动 JavaScript 发展的技术委员会,由各个主流浏览器厂商的汇总代表构成,其主要工作就是最新制定 ECMAScript 标准。TC39 每两个月举行一次会议。进展对于新提案,汇总从提出到最后被纳入 ECMAScript 新特性,TC39 的规范中分为五步:
- Stage 0(strawman),任何TC39的成员都可以提交。
- Stage 1(proposal),进入此阶段就意味着这一提案被认为是正式的了,需要对此提案的场景与API进行详尽的描述。
- Stage 2(draft),这一阶段的提案如果能最终进入到标准,那么在之后的阶段都不会有太大的变化,因为理论上只接受增量修改。
- Stage 3(candidate),这一阶段的提案只有在遇到了重大问题才会修改,规范文档需要被全面的完成。
- Stage 4(finished),这一阶段的提案将会被纳入到ES每年发布的规范之中。
附: ECMAScript 2023(ES14)已于 6 月 27 日正式发布,详见 >>> 《ECMAScript 2023 正式发布,有哪些新特性?》
该 提案[1] 用于简化数组(和可迭代对象)中的分组操作。数组分组是一种非常常见的操作,其将相似的数据组合成组允许开发者计算更高阶的数据集。
const array = [1, 2, 3, 4, 5];// Object.groupBy 根据任意键对元素进行分组,这里通过奇偶数对元素进行分组。Object.groupBy(array, (num, index) => { return num % 2 === 0 ? 'even': 'odd';});// => { odd: [1, 3, 5], even: [2, 4] }// Map.groupBy 返回一个 Map 对象,方便使用对象键进行分组。const odd = { odd: true };const even = { even: true };Map.groupBy(array, (num, index) => { return num % 2 === 0 ? even: odd;});// => Map { { odd: true}: [1, 3, 5], { even: true}: [2, 4] }
该提案提供了两个方法:Object.groupBy 和 Map.groupBy。前者返回一个没有原型的对象,可以方便地进行解构操作,并且可以防止与全局 Object 属性发生意外冲突。后者返回一个普通的 Map 实例,可以对复杂键类型进行分组(比如复合键或元组)。
当手动创建一个 Promise 时,用户必须传递一个执行器回调函数,该函数接受两个参数:
如果回调函数可以嵌入调用一个最终触发解决或拒绝的异步函数(例如注册事件监听器),则这种方式可以很好地工作。
const promise = new Promise((resolve, reject) => { asyncRequest(config, response => { const buffer = []; response.on('data', data => buffer.push(data)); response.on('end', () => resolve(buffer)); response.on('error', reason => reject(reason)); });});
然而,通常开发人员希望在实例化 Promise 后配置其解决和拒绝行为。目前,这需要一个繁琐的解决方法,从回调范围中提取 resolve 和 reject 函数:
let resolve, reject;const promise = new Promise((res, rej) => { resolve = res; reject = rej;});asyncRequest(config, response => { const buffer = []; response.on('callback-request', id => { promise.then(data => callback(id, data)); }); response.on('data', data => buffer.push(data)); response.on('end', () => resolve(buffer)); response.on('error', reason => reject(reason));});
开发人员可能还有其他要求,需要将 resolve/reject 传递给多个调用方,因此必须以这种方式实现:
let resolve = () => { };let reject = () => { };function request(type, message) { if (socket) { const promise = new Promise((res, rej) => { resolve = res; reject = rej; }); socket.emit(type, message); return promise; } return Promise.reject(new Error('Socket unavailable'));}socket.on('response', response => { if (response.status === 200) { resolve(response); } else { reject(new Error(response)); }});socket.on('error', err => { reject(err);});
Promise.withResolvers[2] 提案简单地在 Promise 构造函数中添加了一个静态方法,暂时称为 withResolvers
,该方法返回一个 Promise,并方便地公开其解决和拒绝函数。
const { promise, resolve, reject } = Promise.withResolvers();
无论是对于 JavaScript 还是 WebAssembly,都需要能够更紧密地定制模块的加载、链接和执行,超出了标准的宿主执行模型。
通过将语法模块源导入支持作为新的导入阶段,可以创建一个基础机制,将模块的静态、安全性和工具化优势从 ESM 集成扩展到这些动态实例化用例。
该提案[3]允许ES模块从主机提供的编译后的模块源的反映表达式进行导入:
import source x from "<specifier>";
仅支持上述形式的导入,不支持命名导出和未绑定声明。
动态形式使用 import.<phase>:
const x = await import.source("<specifier>");
通过将阶段作为显式语法的一部分,可以在静态上下文中静态区分全动态导入和仅用于源的导入(无需处理依赖项)。
ECMAScript中的时间区域依赖于IANA时区数据库(TZDB)的标识符,如America/Los_Angeles或Asia/Tokyo。该提案旨在改善开发人员在TZDB中更改时间区域的规范标识符(例如从Europe/Kiev到Europe/Kyiv)时的开发体验。
Temporal.TimeZone.from('Asia/Calcutta');// => Asia/Kolkata(Firefox上当前的Temporal行为)// => Asia/Calcutta(建议:在将标识符返回给调用方时,不要遵循链接)
// 更人性化的标准化相等性测试Temporal.TimeZone.from('Asia/Calcutta').equals('Asia/Kolkata');// => true
JavaScript应用程序可能会变得非常庞大,以至于即使加载它们的初始化脚本,执行起来也会产生显著的性能开销。通常,这种情况发生在应用程序的生命周期较晚的阶段,往往需要进行大规模的改动以提高性能。加载性能是一个重要的改进领域,涉及预加载技术以避免瀑布效应,并使用动态导入进行模块的惰性加载。
尽管使用了这些技术解决了加载性能问题,但代码本身的编写方式仍会导致执行性能开销和CPU瓶颈在初始化过程中出现。
该提案[5]是引入一种新的导入语法形式,它将始终返回一个命名空间对象。在使用时,模块及其依赖项不会被执行,但会完全加载到可以执行的状态,然后才会认为模块图已加载完成。只有当访问该模块的属性时,才会执行相应的操作。
该API将使用以下语法:
// 或使用自定义关键字: import defer * as yNamespace from "y";
现在只有其中 10 个具有DataView的 get/set 方法。
该提案[6]旨在添加DataView.prototype.getUint8Clamped和DataView.prototype.setUint8Clamped方法。
该提案[7]建议在赋值运算符左侧添加对可选链的支持:a?.b = c。在实际开发中,经常需要对对象的属性进行赋值,但前提是该对象确实存在。
通常的做法是使用if语句来保护赋值操作:
if (obj) { obj.prop = value;}
新语法和现有语法对比如下:
[1]提案: https://github.com/tc39/proposal-array-grouping。
[2]Promise.withResolvers: https://github.com/tc39/proposal-promise-with-resolvers。
[3]提案: https://github.com/tc39/proposal-source-phase-imports。
[4]Time Zone Canonicalization: https://github.com/tc39/proposal-canonical-tz。
[5]提案: https://github.com/tc39/proposal-defer-import-eval。
[6]提案: https://github.com/tc39/proposal-dataview-get-set-uint8clamped。
[7]提案: https://github.com/tc39/proposal-optional-chaining-assignment。
责任编辑:姜华 来源: 前端充电宝 TC39JavaScript(责任编辑:时尚)
Android中深入学习对象的四种引用类型(强引用、软引用、弱引用、虚引用)
中青旅(600138.SH):2020年度由盈转亏 基本每股亏损0.3206元
高度致敬Windows!开源优麒麟20.04 LTS发布:支持5年