ECMAScript 双月报告:TC39 2022年12月会议提案进度汇总

简介: 在本次会议中,Intl.Enumeration 提案成功进入到 Stage 4,距离它在 2020 年 6 月的会议上进入到 Stage 1 已经过去了两年半的时间,其它备受关注的提案如 Explicit Resource Management 与 Set Methods也成功取得进展,进入到 Stage 3 阶段。Stage 3 → Stage 4从 Stage 3 进入到 Stage 4 有以

在本次会议中,Intl.Enumeration 提案成功进入到 Stage 4,距离它在 2020 年 6 月的会议上进入到 Stage 1 已经过去了两年半的时间,其它备受关注的提案如 Explicit Resource Management 与 Set Methods也成功取得进展,进入到 Stage 3 阶段。

Stage 3 → Stage 4

从 Stage 3 进入到 Stage 4 有以下几个门槛:

  1. 必须编写与所有提案内容对应的  tc39/test262测试,用于给各大 JavaScript 引擎和 transpiler 等实现检查与标准的兼容程度,并且 test262 已经合入了提案所需要的测试用例;
  2. 至少要有两个实现能够兼容上述 Test 262 测试,并发布到正式版本中;
  3. 发起了将提案内容合入正式标准文本  tc39/ecma262的 Pull Request,并被 ECMAScript 编辑签署同意意见。

Intl.Enumeration

提案链接:proposal-intl-enumeration

这一提案用于获取当前运行环境下国际化选项的支持值,如 calendar、currency、timeZone 等,其引入了 Intl.supportedValuesOf(key) 方法来返回对应的所有支持值,如获取当前运行环境中所有支持的历法:

console.log(Intl.supportedValuesOf('calendar')); 
// ['buddhist', 'chinese', 'coptic', 'dangi', ...]

Stage 2 → Stage 3

提案从 Stage 2 进入到 Stage 3 有以下几个门槛:

  1. 撰写了包含提案所有内容的标准文本,并有指定的 TC39 成员审阅并签署了同意意见;
  2. ECMAScript 编辑签署了同意意见。

Set Methods

提案链接:proposal-set-methods

此提案为 JavaScript 中的 Set 结构新增了一批内置方法,主要为集合相关,包括交集、并集、差集、子集等:

  • Set.prototype.intersection(other)
  • Set.prototype.union(other)
  • Set.prototype.difference(other)
  • Set.prototype.symmetricDifference(other)
  • Set.prototype.isSubsetOf(other)
  • Set.prototype.isSupersetOf(other)
  • Set.prototype.isDisjointFrom(other)

这些方法的入参均为另一个 Set 类型的数据,或者至少是实现了 .size .keys .has 三个方法的对象。

Well-formed Unicode strings

提案链接:proposal-is-usv-string

ECMAScript 字符串都是 UTF-16 编码的字符串。在 Web API 中,我们可以发现有些 API (如 URL、URLSearchParams 等等系列 API)都声明了需要 USVString 作为参数。什么是 USVString?USV 代表 Unicode Scalar Value,即 Unicode 标量值。根据 Unicode 定义,Unicode 的码位(Code Point)可以分成几个类别,分别是图形码(Graphic),格式码(Format),控制码(Control),私有码(Private-Use),代理码(Surrogate),非字符码(Noncharacter),与保留码(Reserved)。而其中的代理码又分成了高位代理码与低位代码码,只有当一个高位代码码与一个低位代理码组合成一个代理码对,才是一个合法的 Unicode 字符。

目前,JavaScript 字符串并不限制这个字符串的值是否是合法的 Unicode 值,比如我们可以编码一个字符串只有高位代理码,而没有低位代理码等等。而如严格的 Web URL API 定义必须要求参数字符串是合法的 Unicode 标量值,因此我们需要有方法能够去区分一个字符串是否是合法的 Unicode 标量值。

这个提案提出为 ECMAScript 引入新的内置方法 String.prototype.isWellFormed,  用于检查这个字符串是否是一个合法的 Unicode 标量值:

'\ud800'.isWellFormed(); // => false
'\ud800\udc00'.isWellFormed(); // => true

另外此提案也提供了 String.prototype.toWellFormed 方法,来将普通字符串转换到一个格式正确的 USV 字符串。类似的,NodeJs 中也提供了 util.toUSVString这样的方法来实现此功能。

你也可以使用其提供的 polyfill string.prototype.iswellformed和 string.prototype.towellformed来提前试用。

Explicit Resource Management

提案链接:proposal-explicit-resource-management

此提案旨在为 JavaScript 中引入显式的资源管理能力,通过统一的 using 关键字来标记当前块级作用域内的关键资源。

在此前,JavaScript 中对各种资源的管理方式并不统一,如在 Generator 函数中,通过 return 方法来提供执行清理逻辑的方式:

function * g() {
  const handle = acquireFileHandle();
  try {
    ...
  }
  finally {
    handle.release(); // 释放资源
  }
}

const obj = g();
try {
  const r = obj.next();
  ...
}
finally {
  obj.return(); // 显式调用函数 g 中的 finally 代码块
}

而通过 using 关键字,其可以被简化为如下的方式:

function * g() {
  using handle = acquireFileHandle(); // 定义与代码块关联的资源
}

{
  using obj = g(); // 显式声明资源
  const r = obj.next();
} // 自动调用释放逻辑

除此以外,NodeJs FileHandles 上的 handle.close() 方法,WHATWG Stream Readers 上的 reader.releaseLock() 均可以使用这种方式来简化资源的管理。

实际上,这里的“显式”对应的是此前如 WeakSet 与 WeakMap 这样,会由运行时作为垃圾回收的一部分进行的“隐式”工作。显式资源管理意味着用户主动声明块级作用域内依赖的资源,通过 Symbol.disposable这样的命令式或 using 这样的声明式,然后在离开作用域时自动地释放这些标记的资源。

Stage 1 → Stage 2

从 Stage 1 进入到 Stage 2 需要完成撰写包含提案所有内容的标准文本的初稿。

ArrayBuffer transfer

提案链接:proposal-arraybuffer-transfer

这一提案属于 proposal-resizablearraybuffer提案的衍生,其引入了 ArrayBuffer.prototype.transfer 方法,来支持对 ArrayBuffer 的所有权转移能力。

在 JavaScript 中,可转移对象指的是拥有可在不同上下文间转移的资源的对象,在转移资源后,原始上下文中的对象将不再指向资源,只有新的上下文持有资源的所有权。这一能力通常用于确保在同一时刻只有一个线程能够访问资源。更常见的一个例子是在 Web Worker 场景下,将可转让对象(比如一个 ArrayBuffer)在主线程与工作线程之间传递,传递方仍然持有原始 ArrayBuffer 对象,但其 byteLength 为0,同时无法再对其进行写入。这一过程无需经过任何拷贝操作,也就意味着在数据量较大时能够有明显的性能提升。

此前我们并不能直接将一个 ArrayBuffer 的资源所有权转移到另一个 ArrayBuffer 对象,以此来避免原始的缓冲区输入被篡改,而只能使用 slice 方法来复制一个 ArrayBuffer 对象,如以下这个例子:

function validateAndWriteSafeButSlow(arrayBuffer) {
	// 复制一份,避免缓冲区被篡改
  const copy = arrayBuffer.slice();

  await validate(copy);
  await fs.writeFile("data.bin", copy);
}

const data = new Uint8Array([0x01, 0x02, 0x03]);

validateAndWrite(data.buffer);

setTimeout(() => {
  // 篡改数据
  data[0] = data[1] = data[2] = 0x00;
}, 50);

这种方式需要将原本的 ArrayBuffer 中的每个字节进行复制,然后开辟新的缓冲区存放,在数据量较大将导致性能问题。而现在,我们可以使用 transfer 方法来直接转移其所有权,使得其无法被篡改:

function validateAndWriteSafeAndFast(arrayBuffer) {
  // 转移所有权,并直接移动而非复制数据
  const owned = arrayBuffer.transfer();

  assert(arrayBuffer.detached);

  await validate(owned);
  await fs.writeFile("data.bin", owned);
}

这里的 arrayBuffer.detached 属性也来自与此提案,用于作为一种清晰且权威的方式,来检查一个 ArrayBuffer 对象是否已从缓冲区分离。

Stage 0 → Stage 1

从 Stage 0 进入到 Stage 1 有以下门槛:

  1. 找到一个 TC39 成员作为 champion 负责这个提案的演进;
  2. 明确提案需要解决的问题与需求和大致的解决方案;
  3. 有问题、解决方案的例子;
  4. 对 API 形式、关键算法、语义、实现风险等有讨论、分析。 Stage 1 的提案会有可预见的比较大的改动,以下列出的例子并不代表提案最终会是例子中的语法、语义。

Intl MessageResource

提案链接:proposal-intl-message-resource

Intl MessageResource 提案是对 Intl.MessageFormat 提案的进一步补充,用于实现一次性对一组资源消息的翻译能力,这是因为 UI 界面中通常同时会存在一组相关联的消息需要翻译,如对话框等。

对于 Intl.MessageFormat 提案,我们的使用方式是这样的,首先给到 MF2 定义:

morning_greeting = {早上好,{$user}!}

new_notifications [$count] =
  [0]   你现在还没有信息
  [one] 你收到新信息了~
  [_]   你收到了 {$count} 条新信息,快打开看看吧!

MF2 的全称为 MessageFormat 2.0,是由message-format-wg制定的,统一的消息描述规范。它是编程语言无关的,目前实现了 MessageFormat 2.0 的语言主要包括 JavaScript和 Java

这里定义了无消息、单条消息、多条消息的几种情况,然后在 JavaScript 中就可以通过创建 Intl .MessageFormat 的实例,来进行消息的解析:

const resource = ... // 即以上的 MF2 定义
const mf1 = new Intl.MessageFormat(resource, ['en']);
const msg1 = mf.resolveMessage('new_notifications', { count: 3 });
msg1.toString(); // '你收到了 3 条新信息,快打开看看吧!'

const mf2 = new Intl.MessageFormat(resource, ['en']);
const msg2 = mf.resolveMessage('morning_greeting', { user: '小明' });
msg2.toString(); // '早上好,小明'

可以看到,对于同一个 MF2 定义,需要创建两个 Intl.MessageFormat 实例来分别进行解析。而 Intl Message Resource 提案为 Intl.MessageFormat 新增了 parseResource 静态方法,使得我们可以一次性完成对所有消息资源的解析:

const resource = ... // 即以上的 MF2 定义
const res = Intl.MessageFormat.parseResource(resource, ['en']);

const greeting = res.get('morning_greeting').resolveMessage({ user: '小明' });
greeting.toString(); // '早上好,小明'

const notifications = res.get('new_notifications').resolveMessage({ count: 3 });
notifications.toString(); // '你收到了 3 条新信息,快打开看看吧!'

另外,MessageFormatter 系列相关提案将引入的 API 具体格式还未完全确定,最终将取决于 MF2 工作组最终为 MF2 落地的语法。

Intl.era and monthCode

提案链接:proposal-intl-era-monthcode

这一提案属于 ECMAScript 402 中的 Intl 提案,与我们更熟悉的 Temporal 提案不同的是,Temporal 仅对 ISO8601 时间格式与 UTC 时区下的行为做了明确定义,对 ISO8601 以外的时间格式和 UTC 以外的时区,只提供了最基本的定义。而 Intl.era 提案旨在对这些规范细节进行进一步的完善。

这一提案之所以没有被作为 Temporal 提案的一部分,原因在于 Temporal 是 ECMA262 规范(即 ECMAScript)的一部分,其需要在所有支持 ECMAScript 的环境中运行并保持一致性,而 Intl 提案所属的 ECMAScript 402 作为 ECMAScript 的国际化标准,其在运行时可能会受到限制,如仅保留少数语言支持,此提案的行为也可能受到影响。

Mass Proxy Revocation

提案链接:proposal-mass-proxy-revocation

在 JavaScript 中,我们可以通过 Proxy.revocable 方法来创建一个可被撤销的代理对象,其返回值中将包含一个 revoke方法,调用此方法就将撤销掉一起生成的代理对象,而后续对此代理对象的所有可代理操作都将抛出错误。但这种方式仅适用于使用 revocable 方法创建的代理对象,同时需要为每个对象都调用一次 revoke方法。

而此提案引入了 createSignal 与 finalizeSignal 方法,来支持一次性对一批 Proxy 对象的撤销,甚至是直接通过 new Proxy 创建的代理对象也能够通过这种方式撤销,其使用方式大致如下:

const s1 = Proxy.createSignal();

const p1 = new Proxy([], {}, { signal: s1 });
const { proxy: p2, revoke } = Proxy.revocable({}, {}, { signal: s1 });

Proxy.finalizeSignal(s1); // p1 与 p2 都将被撤销

总结

对 ECMAScript 有新想法、新需求?快来了解 TC39 是如何工作的( https://yuque.antfin-inc.com/esnext/how-we-work/fgqi7o),或者直接与 @昭朗 联系,加入 ESNext 研讨会小组(钉钉群号23188462)与我们讨论。

相关文章
|
缓存 Ubuntu Linux
LXC (Linux 虚拟环境)简单介绍
LXC是Linux containers的简称,操作系统级别的虚拟化技术。它可以在操作系统层次上为进程提供的虚拟的执行环境。一个虚拟的执行环境被称为一个容器(container)。可以为容器绑定特定的cpu和memory节点,分配特定比例的cpu时间、IO时间,限制可以使用的内存大小(包括内存和是swap空间),提供device访问控制,提供独立的namespace(网络、pid、ipc、mnt、uts)。
1561 0
LXC (Linux 虚拟环境)简单介绍
|
安全 物联网 数据安全/隐私保护
WLAN和WiMax之间的区别
【8月更文挑战第23天】
397 0
|
SQL 缓存 关系型数据库
Mysql跨库操作
Mysql跨库操作
473 0
|
人工智能 自然语言处理 算法
可自主进化的Agent?首个端到端智能体符号化训练框架开源了
【8月更文挑战第13天】近年来,AI领域在构建能自主完成复杂任务的智能体方面取得重大突破。这些智能体通常基于大型语言模型,可通过学习适应环境。为简化设计流程,AIWaves Inc.提出智能体符号化学习框架,使智能体能在数据中心模式下自我优化,以推进通向通用人工智能的道路。该框架将智能体视作符号网络,利用提示、工具及其组合方式定义可学习的权重,并采用自然语言模拟反向传播和梯度下降等学习过程,指导智能体的自我改进。实验显示,此框架能有效促进智能体的自主进化。尽管如此,该框架仍面临高质量提示设计及计算资源需求高等挑战。论文详情参见:https://arxiv.org/pdf/2406.18532。
482 58
|
存储 监控 安全
Star Tower:区块链创新的关键拼图与卓越优势
在当今科技浪潮中,Star Tower 作为区块链领域的新星,凭借智能计算节点、区块链网络、智能合约、客户端应用、网络通信协议和数据存储系统的卓越设计,实现了高效资源利用、数据安全、自动化执行、便捷交互、加密通信和高可用存储,展现出显著的技术优势,有望引领区块链技术迈向新高度。
303 12
|
数据采集 数据安全/隐私保护
​ CDGA|电子行业数据治理六大痛点及突围之道
电子行业在数据治理方面面临着诸多痛点。为了突围而出,企业需要针对这些痛点制定有效的解决方案和措施,包括统一数据标准、打破数据孤岛、保障数据安全、制定合理策略、培养及建立高效团队以及引进先进技术等方面。通过这些努力,企业可以不断提升数据治理的能力和水平,为业务发展提供有力支撑。
|
存储 传感器 监控
云监控:引领未来监控技术的新篇章
传统监控系统需要投入大量的人力物力进行建设和维护,而云监控则通过云计算平台的按需付费特性降低了建设和维护成本。用户只需根据实际需求购买相应的服务和资源即可实现监控功能,无需担心设备升级、维护等问题。
|
机器学习/深度学习 人工智能 自然语言处理
Transformer面试题总结101道
Transformer面试题总结101道
1894 0
|
IDE 算法 自动驾驶
一文搞懂CAN和CAN FD总线协议
这篇文章是将一文搞懂CAN总线协议帧格式和一文搞懂CAN FD总线协议帧格式两篇文章的整合,方便各位朋友学习和查阅。
|
Linux
LINUX下载编译libks
LINUX下载编译libks
322 0