javascript新进展你关注了吗:TC39 东京会议带来五大新特性

上周,JavaScript 语言的掌舵者们齐聚东京。在 Sony Interactive Entertainment 的主持下,Ecma 国际 TC39 委员会召开了第 104 次全体会议,一系列围绕 迭代器(Iterator)Promise 的提案取得了重要进展。这些新特性将让 JavaScript 开发者写出更简洁、更函数式的代码。

让我们一起来看看这些即将改变你编码方式的新特性。


科普:TC39 与提案流程

在深入了解新特性之前,我们先来快速了解一下它们背后的组织和流程。

TC39 是什么?

TC39 (Technical Committee 39) 是 Ecma International 旗下的技术委员会,专门负责 ECMAScript 标准(即 JavaScript 的规范)的制定和维护。其成员由主流浏览器厂商(如 Google, Mozilla, Apple, Microsoft)以及其他对 Web 技术有影响力的科技公司和专家组成。

提案如何成为标准?

一个新特性从提出到最终进入标准,通常需要经历 5 个阶段(The TC39 Process):

  • Stage 0 (Strawman - 稻草人): 任何想法或建议,用于开启讨论。
  • Stage 1 (Proposal - 提案): 确定问题和解决方案,展示潜在的 API 形式。
  • Stage 2 (Draft - 草稿): 具体的语法和语义描述,此时特性已基本定型。
  • Stage 3 (Candidate - 候选): 规范文本已完成,需要浏览器厂商的实现反馈和用户测试。
  • Stage 4 (Finished - 完成): 至少有两个独立的浏览器实现并通过了测试,准备纳入下一版 ECMAScript 标准。

大概需要多久?

这个过程没有固定的时间表,取决于提案的复杂度和争议程度:

  • 简单特性:可能在 1-2 年内走完流程。
  • 复杂特性:可能需要在 Stage 2 或 Stage 3 停留数年(例如 Temporal 提案)。

通常来说,一旦提案进入 Stage 3,就意味着它极有可能在不久的将来成为标准的一部分,各大浏览器也会开始逐步支持。


1. Iterator Sequencing(迭代器序列化)--- Stage 3

提案地址 : proposal-iterator-sequencing

解决什么问题?

你是否曾经需要把多个迭代器"串联"起来,当作一个来用?在以前,你得用生成器函数配合 yield* 来实现:

ini 复制代码
let lows = Iterator.from([0, 1, 2, 3]);
let highs = Iterator.from([6, 7, 8, 9]);
​
// 以前的写法,略显繁琐
let combined = function* () {
  yield* lows;
  yield* highs;
}();
​
Array.from(combined); // [0, 1, 2, 3, 6, 7, 8, 9]

新写法

现在只需一行:

ini 复制代码
let combined = Iterator.concat(lows, highs);
Array.from(combined); // [0, 1, 2, 3, 6, 7, 8, 9]
​
// 还可以在中间插入其他值
let digits = Iterator.concat(lows, [4, 5], highs);
Array.from(digits); // [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

Iterator.concat() 接受多个可迭代对象,惰性地按顺序产出所有值。这不仅代码更简洁,而且因为是惰性求值,处理大数据集时内存效率也更高。


2. Await Dictionary of Promises(Promise 字典等待)--- Stage 1

提案地址 : proposal-await-dictionary

解决什么问题?

当你需要并发等待多个 Promise 时,Promise.all 返回的是数组,你得靠下标来取值:

scss 复制代码
const [shape, color, mass] = await Promise.all([
  getShape(),
  getColor(),
  getMass(),
]);
// 顺序错了?很容易出 bug

新写法

使用 Promise.allKeyed(),用对象的键来命名你的结果:

scss 复制代码
const { shape, color, mass } = await Promise.allKeyed({
  shape: getShape(),
  color: getColor(),
  mass: getMass(),
});
// 再也不用担心顺序问题了!

该提案还支持 Promise.allSettledKeyed(),用于处理可能失败的场景:

ini 复制代码
const results = await Promise.allSettledKeyed({
  shape: getShape(),
  color: getColor(),
  mass: getMass(),
});
​
if (results.shape.status === "fulfilled") {
  console.log(results.shape.value);
} else {
  console.error(results.shape.reason);
}

这个 API 设计有意与 Iterator.zipKeyed() 保持一致,体现了 TC39 在语言设计上的系统性思考。


3. Joint Iteration(联合迭代)--- Stage 2.7

提案地址 : proposal-joint-iteration

解决什么问题?

Python 开发者对 zip() 函数再熟悉不过了------它能把多个序列"拉链式"地组合在一起。JavaScript 一直缺少这个功能。

新写法

Iterator.zip()Iterator.zipKeyed() 填补了这个空白:

php 复制代码
// 位置对应的组合
Array.from(Iterator.zip([
  [0, 1, 2],
  [3, 4, 5],
]))
// 结果: [[0, 3], [1, 4], [2, 5]]
​
// 用键名组合
Iterator.zipKeyed({
  a: [0, 1, 2],
  b: [3, 4, 5, 6],
  c: [7, 8, 9],
}).toArray()
// 结果: [
//   { a: 0, b: 3, c: 7 },
//   { a: 1, b: 4, c: 8 },
//   { a: 2, b: 5, c: 9 }
// ]

还支持三种模式来处理长度不等的迭代器:

  • mode: 'shortest'(默认):最短的迭代器耗尽时停止
  • mode: 'longest':最长的迭代器耗尽时停止,可以指定填充值
  • mode: 'strict':如果长度不等则抛出错误
php 复制代码
Iterator.zipKeyed({
  a: [0, 1, 2],
  b: [3, 4, 5, 6],
  c: [7, 8, 9],
}, {
  mode: 'longest',
  padding: { c: 10 },
}).toArray()
// 结果包含: { a: undefined, b: 6, c: 10 }

4. Iterator Join(迭代器连接)--- 新提案

提案地址 : proposal-iterator-join

解决什么问题?

Array.prototype.join() 能把数组元素用分隔符连接成字符串。但如果你有一个迭代器呢?现在你得先转成数组:

csharp 复制代码
myIterator.toArray().join(', ') // 先全部加载到内存

新写法

Iterator.prototype.join() 让你直接在迭代器上操作:

csharp 复制代码
Iterator.from(['a', 'b', 'c']).join(', ')
// 结果: "a, b, c"

这对于处理大型或无限序列(只取部分)时特别有用,避免了不必要的内存分配。


5. Typed Array Find Within(类型数组范围查找)

解决什么问题?

现有的 TypedArray.prototype.indexOf() 只能从数组开头或指定位置向后搜索。当你需要在特定范围内查找时,现有 API 不够灵活。

新能力

这个提案为 TypedArray 添加了在指定范围内进行查找的能力,让二进制数据处理更加高效。这对于处理音视频数据、WebGL 缓冲区、以及其他需要精确控制搜索范围的场景非常有用。


迭代器生态的完善

如果你一直关注 TC39 的动态,你会发现这次会议推进的提案有一个共同主题:完善 JavaScript 的迭代器生态

提案 功能 状态
Iterator Helpers map, filter, take, drop 等 ✅ Stage 4(已标准化)
Iterator Sequencing concat Stage 3
Joint Iteration zip, zipKeyed Stage 2.7
Iterator Join join 新提案
Await Dictionary Promise.allKeyed Stage 1

参考链接:

相关推荐
丢,捞仔8 小时前
uni-app上架应用添加权限提示框
前端·javascript·uni-app
Hilaku8 小时前
我是如何用一行 JS 代码,让你的浏览器内存瞬间崩溃的?
前端·javascript·node.js
哈__8 小时前
React Native 鸿蒙跨平台开发:简易记事本 APP
javascript·react native·react.js
贺今宵8 小时前
electron-vue无网络环境,读取本地图片/文件展示在页面vue中protocol
前端·javascript·electron
老前端的功夫8 小时前
TypeScript索引访问类型深度解析:类型系统的动态访问与模式匹配
前端·javascript·ubuntu·架构·typescript·前端框架
张元清8 小时前
大白话讲 React2Shell 漏洞:智能家居的语音助手危机
前端·javascript·react.js
boooooooom8 小时前
手写高质量深拷贝:攻克循环引用、Symbol、WeakMap等核心难点
javascript·面试
Irene19918 小时前
使用 TypeScript 编写一个 Vue 3 模态框(Modal)组件
javascript·vue.js·typescript
踢球的打工仔8 小时前
typescript-void和never
前端·javascript·typescript
hugo_im8 小时前
GrapesJS 完全指南:从零构建你的可视化拖拽编辑器
前端·javascript·前端框架