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

参考链接:

相关推荐
北极糊的狐3 小时前
父组件向子组件传参时,传递数组和对象类型的参数的方法
前端·javascript·vue.js
一颗不甘坠落的流星3 小时前
【HTML】iframe 标签 allow 权限汇总(例如添加复制粘贴权限)
前端·javascript·html
forestsea3 小时前
现代 JavaScript 加密技术详解:Web Crypto API 与常见算法实践
前端·javascript·算法
骑自行车的码农5 小时前
🍂 React DOM树的构建原理和算法
javascript·算法·react.js
北极糊的狐5 小时前
Vue3 中父子组件传参是组件通信的核心场景,需遵循「父传子靠 Props,子传父靠自定义事件」的原则,以下是资料总结
前端·javascript·vue.js
看到我请叫我铁锤5 小时前
vue3中THINGJS初始化步骤
前端·javascript·vue.js·3d
q***25215 小时前
SpringMVC 请求参数接收
前端·javascript·算法
谢尔登6 小时前
defineProperty如何弥补数组响应式不足的缺陷
前端·javascript·vue.js
T***u3338 小时前
前端框架在性能优化中的实践
javascript·vue.js·前端框架