TypedArray Find Within S1
中文标题:TypedArray 内部查找
- 阶段: Stage 1
- 状态: 进行中
- ECMAScript 版本: —
- 同步时间: 2026年8月26日
- English original · 官方仓库
该提案向 TypedArray.prototype 添加子序列搜索方法(search、searchLast、contains),解决 TypedArray 中缺乏原生高效子序列搜索的问题。它定义了 needle 类型、可选的位置参数,并将算法实现留给引擎。
以下 README 来自上游仓库,其中的阶段或状态标注可能滞后;当前信息以提案概览为准。
TypedArray 内部查找
ECMAScript 提案,用于在 TypedArray 中搜索子序列
问题
ECMAScript 应为 TypedArray 提供一种原生的 indexOf 类型方法,用于搜索元素子序列。
如今使用 TypedArray,可以获取特定单个元素的索引,但没有机制来高效定位元素序列。子序列搜索在服务器端应用程序(如 Node.js)中已经常见了一段时间,通过 Buffer 对象对 Uint8Array.prototype.indexOf 方法的覆盖实现,但这在 Web 上的 TypedArray 中并未普遍支持,这迫使应用程序实现缓慢的替代方案,通常依赖于对数组进行非优化的线性搜索。
提案
该提案是向 TypedArray.prototype 添加 API,以支持三种形式的优化子序列搜索:search 返回第一次出现的起始索引,searchLast 返回最后一次出现的起始索引,contains 如果子序列存在则返回简单的布尔值 true/false。所有三个方法都接受可选的 position 参数来控制搜索的起始位置。对于 search 和 contains,仅考虑从 position 或之后开始的匹配。对于 searchLast,仅考虑从 position 或之前开始的匹配。
具体如何实现子序列搜索算法打算留作实现细节。
needle 类型
needle 参数可以是:
- TypedArray(相同或不同的元素类型)——通过其
@@iterator方法进行迭代。每个生成的值必须是与 haystack 类型正确的值(对于非 BigInt TypedArray 为 Number,对于 BigInt TypedArray 为 BigInt);如果任何值类型错误,搜索返回-1。这会创建 needle 元素的快照,这对于当 needle 由 SharedArrayBuffer 支持时的正确性是必要的。 - 可迭代对象(除 String 外)——其元素被收集并针对 haystack 的元素类型进行类型检查。如果任何元素类型错误,搜索返回
-1。 - 字符串——抛出
TypeError。尽管字符串是可迭代的,但其迭代产生码点,这可能不是搜索 TypedArray 时的预期行为。 - 任何其他值——抛出
TypeError。
跨类型浮点精度
当 needle TypedArray 的浮点类型比 haystack 更窄时,通过更窄类型往返可能丢失精度,导致匹配失败。Needle 元素通过 @@iterator 作为 JavaScript 数字读回,当存储在 Float32Array 中被舍入的值将不会与 Float64Array 中更高精度的表示进行 SameValueZero 匹配。
这不是此提案特有的问题——它是 IEEE 754 浮点运算的固有属性,并且同样适用于任何跨类型元素比较。
为什么只针对 TypedArray?为什么不是所有 可迭代对象
该提案通常可以解决在任何可迭代对象中搜索子序列的相同问题。这是委员会应该决定的事情。然而,那里有几个问题:
- 在
haystackTypedArray中专门优化搜索needle的性能比一般处理可迭代协议更容易。虽然该提案处理可迭代对象可能有意义,但该方法中有一组不同的性能和优化路径考虑因素。 - TypedArray 在成员元素上是同质的,字符串也是如此。然而,其他类型的可迭代对象可能产生各种类型的值。虽然可迭代对象总是产生相同类型的值是最常见的,但并非要求如此。这也使得难以在一般情况下进行优化。