我是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]]];
}
}
};
}
// ...
}
如果有任何存在约定我应该遵循(或者此代码有任何问题),我们非常感谢您的反馈。
答案 0 :(得分:1)
您可能会从Map
和Set
ES6数据结构中获得灵感。它们提供了多种方法来获取不同的迭代器:.values()
,.keys()
和.entries()
。他们的@@iterator
方法分别默认为entries
或values
。
我不知道任何其他现有惯例,我想这些必须要形成。
此代码的任何问题
首先,我不确定返回此类对象的getter vertices
是否是个好主意。我宁愿做
get vertexCount() { … }
vertices*() { … }
但这基本上归结为偏好。您当前的代码效率不高,因为它会在每次.vertices
访问时创建两个函数,如果您看到需要,可以使用原型来改进它(class VertexIterator {…}
?)。
其次,可变数据的迭代器实现起来很麻烦,因为它可能会在循环时发生变化。你应该意识到这一点,并选择一个策略(使你的结构不可变可能是不可能的)。例如,MapIterator的next
方法被指定为&#34; 每次评估时都会重新确定元素的数量。&#34;。类似地,对于对象枚举(for in
),有一条规则,即删除的属性必须永远不会出现(如果在删除它们之前尚未枚举),当然也不能枚举两次属性。但是,它们明确地允许在执行期间添加的键不一致,不保证它们是否出现在枚举中。