TypedArray Concat S1
中文标题:类型化数组连接
- 阶段: Stage 1
- 状态: 进行中
- ECMAScript 版本: —
- 同步时间: 2026年8月26日
- English original · 官方仓库
该提案为 %TypedArray%、ArrayBuffer 和 SharedArrayBuffer 引入静态 concat 方法,以解决这些缓冲区类型简洁连接的需求。%TypedArray%.concat 处理同类型 TypedArray 的面向元素的连接,而缓冲区级别的方法支持面向字节的连接,并提供调整大小、增长或不可变性的选项。
以下 README 来自上游仓库,其中的阶段或状态标注可能滞后;当前信息以提案概览为准。
TypedArray、ArrayBuffer 和 SharedArrayBuffer 的连接
ECMAScript 提案:TypedArray、ArrayBuffer 和 SharedArrayBuffer 的连接
问题
连接 TypedArray 和 ArrayBuffer 是一种常见操作,目前需要繁琐的手动缓冲区分配和数据复制;语言原生的 concat 方法将简化这一常见模式。
Web 应用(无论是浏览器端还是服务器端)通常需要在数据管道中连接两个或多个 TypedArray 或 ArrayBuffer 实例。不幸的是,用于连接的现有机制相当冗长。
一个常见示例是 WritableStream 实例,它在将写入数据作为一个合并块传递之前,会收集写入数据直到达到定义的阈值。服务器端应用通常依赖 Node.js 的 Buffer.concat API,而浏览器端应用则依赖浏览器兼容的 Buffer polyfill 或 TypedArray.prototype.set。
虽然这些方法可行,但它们需要大量冗长的样板代码。
提案
本提案提供了三个互补的静态连接方法:
%TypedArray%.concat(items [, length])— 对相同类型的 TypedArray 进行面向元素的连接ArrayBuffer.concat(items [, options])— 面向字节的连接,返回 ArrayBufferSharedArrayBuffer.concat(items [, options])— 面向字节的连接,返回 SharedArrayBuffer
所有这些方法都允许实现确定执行分配和复制的最优方法和最佳时机,但不需要特定的优化。
%TypedArray%.concat 仅接受与构造函数相同类型的 TypedArray(例如,对于 Uint8Array.concat 必须全部是 Uint8Array),但这些 TypedArray 可以由 ArrayBuffer 或 SharedArrayBuffer 支持。ArrayBuffer.concat 和 SharedArrayBuffer.concat 接受 ArrayBuffer、SharedArrayBuffer、TypedArray 和 DataView 输入的任何组合——返回类型由调用的方法决定,而不是由输入类型决定。
%TypedArray%.concat(items [, length])
将多个同类型的 TypedArray 连接成一个新的 TypedArray。
items— TypedArray 实例的可迭代对象,所有实例类型与构造函数相同。length(可选)— 一个非负整数,指定结果的元素长度。如果小于总长度,结果将被截断;如果大于总长度,则零填充;默认为所有输入长度的总和。
所有条目必须是与构造函数相同类型的 TypedArray(例如,对于 Uint8Array.concat,所有条目必须是 Uint8Array)。如果任何条目类型不同,则抛出 TypeError。条目可以由 ArrayBuffer 或 SharedArrayBuffer 支持。
如果任何条目是已分离的 TypedArray,则抛出 TypeError。如果总元素数超过 253 - 1,则抛出 RangeError。
concat 方法在所有 TypedArray 构造函数上可用:
ArrayBuffer.concat(items [, options])
将多个 ArrayBuffer、SharedArrayBuffer、TypedArray 或 DataView 的字节内容连接成一个新的 ArrayBuffer。
items— ArrayBuffer、SharedArrayBuffer、TypedArray 或 DataView 实例的可迭代对象。对于 TypedArray 和 DataView 输入,仅包含底层缓冲区的视图部分。options(可选)— 包含以下属性的对象:length— 一个非负整数,指定结果的字节长度。如果小于总输入字节数,结果将被截断;如果大于总输入字节数,则零填充;默认为所有输入字节长度的总和。resizable— 布尔值。如果为true,结果是可调整大小的 ArrayBuffer,其中length指定最大字节长度(maxByteLength)。实际byteLength是总输入字节数与length中的较小值。默认为false。immutable— 布尔值。如果为true,结果是不可变的 ArrayBuffer,其内容无法更改、调整大小或分离。默认为false。此选项依赖于 `Immutable ArrayBuffer {proposal](https://github.com/tc39/proposal-immutable-arraybuffer)。
resizable 和 immutable 选项互斥。如果两者都为 true,则抛出 TypeError。
如果缓冲区已分离或 DataView 越界,则抛出 TypeError。如果总字节数超过 253 - 1,则抛出 RangeError。
SharedArrayBuffer.concat(items [, options])
将多个 ArrayBuffer、SharedArrayBuffer、TypedArray 或 DataView 的字节内容连接成一个新的 SharedArrayBuffer。
items— ArrayBuffer、SharedArrayBuffer、TypedArray 或 DataView 实例的可迭代对象。对于 TypedArray 和 DataView 输入,仅包含底层缓冲区的视图部分。options(可选)— 包含以下属性的对象:length— 一个非负整数,指定结果的字节长度。如果小于总输入字节数,结果将被截断;如果大于总输入字节数,则零填充;默认为所有输入字节长度的总和。growable— 布尔值。如果为true,结果是可增长的 SharedArrayBuffer,其中length指定最大字节长度(maxByteLength)。实际byteLength是总输入字节数与length中的较小值。默认为false。
注意:immutable 选项不适用于 SharedArrayBuffer。
如果缓冲区已分离或 DataView 越界,则抛出 TypeError。如果总字节数超过 253 - 1,则抛出 RangeError。
与 set 的差异
根据语言规范中 TypedArray.prototype.set 的当前定义,用户代码需要提前分配目标 TypedArray,并计算和更新每个复制段的偏移量。当有多个输入 TypedArray 时,分配可能很昂贵,簿记也可能很繁琐。set 算法也被设计为将复制的 TypedArray 的每个元素逐个复制到目标,不允许实现选择替代的、更优化的复制策略。
为什么三个方法?
%TypedArray%.concat 在 TypedArray 级别操作——它是面向元素的,要求相同类型的输入,并返回 TypedArray。这是处理类型化数据时正确的抽象级别(例如,在流中连接 Uint8Array 块)。
ArrayBuffer.concat 和 SharedArrayBuffer.concat 在缓冲区级别操作——它们是面向字节的,接受异构输入(ArrayBuffer/SharedArrayBuffer、TypedArray、DataView),并返回适当的缓冲区类型。这是控制缓冲区属性(如可调整大小/可增长性和不可变性)的正确抽象级别,这些属性是缓冲区的关注点,而不是 TypedArray 的关注点。
ArrayBuffer.concat 和 SharedArrayBuffer.concat 是单独的方法,因为返回类型不同,可用选项也不同(immutable 仅适用于 ArrayBuffer,growable 仅适用于 SharedArrayBuffer)。这反映了语言中 ArrayBuffer 和 SharedArrayBuffer 构造函数之间的现有分离。