For AI agents: the complete documentation index is available at /tc39-atlas/llms.txt, the full documentation bundle is available at /tc39-atlas/llms-full.txt, and this page is available as Markdown at /tc39-atlas/proposals/stage/4/proposal-array-find-from-last.md.
  • 简体中文
  • Array find from last S4

    中文标题:数组从末尾开始查找

    提案概览
    提案速览

    该提案为数组和类型化数组的原型添加了 findLast()findLastIndex() 方法,允许开发者根据条件从数组末尾向前查找元素或其索引。它解决了迭代向后但不需变更或复杂索引计算的需求,而这些是 \[.arr\].reverse().find() 等变通方法所必需的。

    Note

    以下 README 来自上游仓库,其中的阶段或状态标注可能滞后;当前信息以提案概览为准。

    proposal-array-find-from-last

    为数组和类型化数组添加 .findLast().findLastIndex() 方法的提案。

    状态

    这是一个 第 4 阶段提案

    动机

    在数组中查找元素是一种非常常见的编程模式。

    该提案有一个主要关注点:语义。这意味着“清晰地表达我想要的操作”。

    并且随着这些变化,这里有一个额外好处:性能。避免明显的开销,并可能改善时间复杂度中的常数因子。 即使没有数量级的变化,但在一些对性能敏感的場景中可能很有用。例如:React 渲染函数。


    ECMAScript 目前支持 {Array, %TypedArray%}.prototype.indexOf{Array, %TypedArray%}.prototype.lastIndexOf 来查找数组中某个 value 的索引。

    还有 {Array, %TypedArray%}.prototype.find{Array, %TypedArray%}.prototype.findIndex 来查找满足给定条件的元素或其索引。

    然而,该语言并未提供一种使用条件函数从后到前查找数组元素的方法。

    [...[]].reverse().find() 是一种变通方法,但存在两个问题:

    1. 不必要的变更(由 reverse 造成)。
    2. 不必要的复制(为了避免变更)

    对于 .findIndex(),你需要在调用方法后执行额外的步骤(重新计算索引并处理 -1)来计算 [...arr].reverse().findIndex() 的结果。

    因此还有第三个问题:

    1. 复杂的索引计算

    所以,也许我们需要一些直接且有效的方法。在本提案中,它们是 {Array, %TypedArray%}.prototype.findLast{Array, %TypedArray%}.prototype.findLastIndex

    场景

    • 你知道从后查找可能有更好的性能(目标元素在数组尾部,在队列或栈中可能通过 pushconcat 追加,例如:时间线中最近匹配的时间点)。
    • 你关心元素的顺序(数组中可能有重复项,例如:数字列表中最后一个奇数)。
    • 等等。

    核心特性

    添加 {Array, %TypedArray%}.prototype.findLast{Array, %TypedArray%}.prototype.findLastIndex

    其行为与 Array.prototype.findArray.prototype.findIndex 相同,但从后向前迭代。

    例如:

    const array = [{ value: 1 }, { value: 2 }, { value: 3 }, { value: 4 }];
    
    array.find(n => n.value % 2 === 1); // { value: 1 }
    array.findIndex(n => n.value % 2 === 1); // 0
    
    // ======== 提案之前 =========== 
    
    // find
    [...array].reverse().find(n => n.value % 2 === 1); // { value: 3 }
    
    // findIndex
    array.length - 1 - [...array].reverse().findIndex(n => n.value % 2 === 1); // 2
    array.length - 1 - [...array].reverse().findIndex(n => n.value === 42); // 应该为 -1,但结果是 4
    
    // ======== 提案之中 =========== 
    // find
    array.findLast(n => n.value % 2 === 1); // { value: 3 }
    
    // findIndex
    array.findLastIndex(n => n.value % 2 === 1); // 2
    array.findLastIndex(n => n.value === 42); // -1
    

    幻灯片

    Polyfill

    相关

    提案人

    Champions:

    • @Kingwl (王文路,KWL)
    • @DanielRosenwasser (Daniel Rosenwasser, DRR)