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/proposal-object-iteration.md.
  • 简体中文
  • Improving iteration on Objects ?

    中文标题:改进对对象的迭代

    提案概览
    提案速览

    JavaScript 对象常被用作字典,但默认不可迭代,迫使开发者在使用集合方法前先将其转换为数组。该提案引入了 Object.iterateEntries、Object.iterateKeys 和 Object.iterateValues 等静态方法,直接从对象获取迭代器,从而实现就地迭代并与迭代器辅助方法组合。这种方式允许对对象条目执行诸如映射等操作,而无需中间数组转换。

    Note

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

    已撤回:本提案已从考虑中撤回

    在 2020 年 2 月会议上提出疑虑后,本提案被撤回。

    改进对对象的迭代

    一份 ECMA TC39 提案,旨在改善对对象进行迭代和映射的体验与性能

    基本信息

    • 当前阶段: 1
    • 最后展示: 2020 年 2 月
    • 下次展示: 待定
    • 作者: Jonathan Keslin (@decompil3d) -- GoDaddy
    • 推动者: Jonathan Keslin (@decompil3d) -- GoDaddy

    问题

    对象在 JavaScript 中常被用作事实上的字典类型。但对象默认不可迭代,因此许多可迭代对象上有价值的集合方法在不对对象进行先转换的情况下无法用于对象——需要先将对象转换为数组1

    提议的解决方案

    提供在对象上获取 Iterator 的功能

    // 将结果收集回对象
    Object.fromEntries(
      // 获取对象迭代器的工具方法
      Object.iterateEntries(obj)
        // 作用于可迭代对象的标准 `map` 函数
        .map(([key, value]) => [transform(key), transform(value)])
    );

    具体提议内容

    • Object 上增加至多三个静态方法,以对其存储的数据进行就地迭代:
      • Object.iterateEntries:迭代对象,提供键值对,很像 Map.prototype.entries
      • Object.iterateKeys:迭代对象,仅提供键,像 Map.prototype.keys 一样
      • Object.iterateValues:迭代对象,仅提供值,像 Map.prototype.values 一样
    Object.iterateEntries
    const obj = { foo: 'bar', baz: 'blah' };
    const entriesIterator = Object.iterateEntries(obj);
    for (const [key, value] of entriesIterator) {
      console.log(`${key} -> ${value}`);
    }
    Object.iterateKeys
    const obj = { foo: 'bar', baz: 'blah' };
    const keysIterator = Object.iterateKeys(obj);
    for (const key of keysIterator) {
      console.log(key);
    }
    Object.iterateValues
    const obj = { foo: 'bar', baz: 'blah' };
    const valuesIterator = Object.iterateValues(obj);
    for (const value of valuesIterator) {
      console.log(value);
    }
    与现有 Iterator Helpers 提案的关系
    • Iterator Helpers 提案并非使本提案有用所必需的,但它能大幅改善开发者体验
    • 没有本提案,Iterator Helpers 中提供的辅助方法对存储在对象中的数据价值有限,因为目前没有机制可以就地迭代对象。

    填充库

    core-js 库中提供了非官方填充库。

    本提案的历史

    本提案自最初展示以来发生了一些变化。

    2019 年 10 月

    最初的提案是 Object.map——在 Object 上提供一个静态 API 方法来转换键和/或值,并返回转换后的对象。

    幻灯片:https://1drv.ms/p/s!As13Waij_jkUqeV6IHXsJBMDkNIgXw

    会议决议

    与会者普遍支持改善对对象映射的体验和可优化性,但有人担心添加 map 方法会引发滑坡效应。

    取而代之,我们同意将该提案改为对改进对象映射的探索,并同意进入第 1 阶段。

    会议后讨论

    10 月会议后,本提案和 Iterator Helpers 提案的推动者与作者会面,讨论了两个提案之间的关系。结论是,为此目的增强 Iterator.from 是行不通的,因为对于扩展了 Iterator.prototype 的对象来说会产生歧义。

    由于 Iterator Helpers 提供了所需的 map 机制,本提案可调整为专注于从对象获取 Iterator

    2020 年 2 月

    展示了从“对象映射”到“对象迭代”的变化

    幻灯片:https://1drv.ms/p/s!As13Waij_jkUqe0X3QmI7R9FfKahkw

    提议的规范文本:https://tc39.es/proposal-object-iteration/

    备选规范文本:https://tc39.es/proposal-object-iteration/alt.html

    会议决议

    多位实现者对该 API 的实用性提出了疑虑。他们认为现有的 Object.keysvaluesentries 已经足够好,并且可以很容易地优化。引擎可以很直接地拥有一个“快速”路径,在常见情况下直接优化掉数组实例化,同时为边缘情况(如 Array 原型被污染时)提供较慢的路径。

    还有人担心第二个规范文本选项允许在迭代期间修改底层对象。这与 Array、Set 和 Map 等现有集合一致。但这意味着从使用 keys 转向 iterateKeys 会产生真实的语义差异,可能成为陷阱。

    一些代表认为,更好的做法是尝试引导人们使用更合适的“字典”集合,如 Map,它已经提供了本提案所展示的就地迭代。与会者一致认为从 JSON 获取 Map 并不理想,因此本提案的后续步骤可能是研究改进用于此目的的 reviver。

    后续将进行更多调查。

    注释

    1 具体来说,Object.entriesObject.keysObject.values