说明
使对象可迭代意味着该对象具有一个名为的方法Symbol.iterator
。调用此方法时,应返回一个称为iterator的接口。
该迭代器必须具有next
返回下一个结果的方法。此结果应该是一个对象,该对象的value
属性提供下一个值,而一个done
属性应true
在没有其他结果时提供,false
否则将不存在。
实作
我还将为一个名为的类实现一个迭代器Matrix
,所有元素的范围从0
到width * height - 1
。我将为此迭代器创建一个不同的类,称为MatrixIterator
。
class Matrix {
constructor(width, height) {
this.width = width;
this.height = height;
this.content = [];
for (let y = 0; y < height; y++) {
for (let x = 0; x < width; x++) {
this.content[y * width + x] = y * width + x;
}
}
}
get(x, y) {
return this.content[y * this.width + x];
}
[Symbol.iterator]() {
return new MatrixIterator(this);
}
}
class MatrixIterator {
constructor(matrix) {
this.x = 0;
this.y = 0;
this.matrix = matrix;
}
next() {
if (this.y == this.matrix.height) return {done: true};
let value = {
x: this.x,
y: this.y,
value: this.matrix.get(this.x, this.y)
};
this.x++;
if (this.x == this.matrix.width) {
this.x = 0;
this.y++;
}
return {value, done: false};
}
}
注意,它通过定义符号来Matrix
实现迭代器协议Symbol.iterator
。在此方法内部,MatrixIterator
创建this
的Matrix
实例,该实例使用,即该实例作为参数,并在 MatrixIterator
方法next
内部定义。我特别喜欢这种实现迭代器的方式,因为它清楚地显示了迭代器和的实现Symbol.iterator
。
或者,也不能直接定义Symbol.iterator
,而是添加一个函数,prototype[Symbol.iterator]
如下所示:
Matrix.prototype[Symbol.iterator] = function() {
return new MatrixIterator(this);
};
使用范例
let matrix = new Matrix(3, 2);
for (let e of matrix) {
console.log(e);
}
v8.1.1