【问题标题】:Conventions for ES6 iterables?ES6 可迭代的约定?
【发布时间】:2015-06-01 19:03:07
【问题描述】:

我是 JavaScript 的 graph datastructure library 的作者。我目前是ES6-ifying图书馆。

我还想让它对 ES6 程序员更有用,这意味着实现 iterable protocol。但是一个图有多个要迭代的东西,以及迭代它们的多种方式(顶点、边、后继、前驱、拓扑顺序中的顶点等)

我对如何设计此界面有一个想法,但我想遵循现有的约定(如果存在)。这是我如何执行“顶点”部分的示例:

class JsGraph {
    // ...
    get vertices() {
        return {
            _graph: this,
            get length() { return this._graph._vertexCount },
            *[Symbol.iterator]() {
                var keys = Object.keys(this._graph._vertices);
                for (let i = 0; i < keys.length; ++i) {
                    yield [keys[i], this._graph._vertices[keys[i]]];
                }
            }
        };
    }
    // ...
}

如果我可能应该遵循任何现有约定(或此代码有任何问题),我们将非常感谢您的反馈。

【问题讨论】:

    标签: javascript conventions ecmascript-6 iterable


    【解决方案1】:

    您可能会从MapSet ES6 数据结构中得到一些启发。它们确实提供了多种方法来获取不同的迭代器:.values().keys().entries()。他们的@@iterator 方法分别默认为entriesvalues

    我不知道任何其他现有的约定,我想这些还得形成。

    此代码有任何问题

    首先,我不确定返回此类对象的 getter vertices 是否是个好主意。我宁愿做

    get vertexCount() { … }
    vertices*() { … }
    

    但这基本上取决于偏好。您当前的代码效率不高,因为它在每次 .vertices 访问时创建两个函数,如果您看到需要,您可以使用原型改进它(class VertexIterator {…}?)。

    其次,可变数据上的迭代器很难实现,因为它在循环时可能会发生变化。您应该意识到这一点并选择一种策略(使您的结构不可变可能是不可能的)。例如,MapIterator 的next 方法被指定为“每次评估时重新确定元素的数量。”。类似地,对于对象枚举(for in),有一条规则是删除的属性永远不能出现(如果在它们被删除之前尚未枚举),当然任何属性都不能被枚举两次。但是,它们明确允许在执行期间添加的键不一致,不保证这些键是否出现在枚举中。

    【讨论】:

    • 谢谢!到处都很有用。 [1] 如果MapSet 使用函数调用表示法来获取特定的迭代器,我也会这样做。 [2] 在这种情况下,在那里拥有一个.length 属性(让它感觉像一个数组)在某种程度上失去了它的吸引力,所以我也会接受你的建议。 [3] 一个很好的观点。一开始我的规格可能会比较保守。对象枚举的保证似乎是可以实现的。
    • “第二,可变数据上的迭代器很难实现”,在某些情况下可能会使用写时复制数据结构和/或快照,类似于非实时 DOM 节点列表。
    猜你喜欢
    • 2015-12-30
    • 2015-12-24
    • 2017-07-06
    • 2021-04-21
    • 2020-04-14
    • 2015-02-21
    • 1970-01-01
    • 1970-01-01
    • 2017-05-02
    相关资源
    最近更新 更多