ES6迭代的约定?

时间:2015-03-28 13:41:55

标签: javascript conventions ecmascript-6 iterable

我是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]]];
                }
            }
        };
    }
    // ...
}

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

1 个答案:

答案 0 :(得分:1)

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

我不知道任何其他现有惯例,我想这些必须要形成。

  

此代码的任何问题

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

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

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

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