我目前正在阅读Eloquent Javascript,而且我听不懂这部分。
我不理解Symbol.iterator部分。能否解释一下它的工作原理。谢谢
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.prototype[Symbol.iterator] = function() {
return new MatrixIterator(this);
};
答案 0 :(得分:2)
Symbol.iterator
是一个well-known symbol(仅表示它已在规范中定义,并且可以作为Symbol
的属性使用),这是JavaScript需要时查找的方法的关键从对象获取 iterator 。 for-of
,...
(在数组上)使用迭代器,这样可以遍历对象的内容。
例如,在此代码中:
const a = [1, 2, 3];
for (const value of a) {
console.log(value);
}
JavaScript引擎在[Symbol.iterator]
上调用a
方法,以获取用于for-of
循环的迭代器。
在同一示例中(大致)直接使用迭代器,而不是让for-of
为我们处理它:
const a = [1, 2, 3];
// Get the iterator
const it = a[Symbol.iterator]();
// Get the first result object from it
let result = it.next();
// While the result object doesn't have done = true...
while (!result.done) {
// Get and show this iteration's value
const value = result.value;
console.log(value);
// Get the next result
result = it.next();
}
关于迭代器的伟大之处在于,它有一种通用的定义方式来获取对象的迭代器,这使得for-of
之类的事情成为可能,而与要迭代的对象是什么无关。例如,字符串是可迭代的(一次只能获得一个字符)。映射是可迭代的(获得的每个值都是一个[key, value]
数组)。等等。对象定义了如何进行迭代以及在迭代过程中提供的值。您可以编写一个简单的链表类并使其可迭代,并且使用它的代码不必关心它是链表,而不是数组或其他任何东西。
在这种情况下,此代码:
Matrix.prototype[Symbol.iterator] = function() {
return new MatrixIterator(this);
};
在原型上创建该方法,该方法将分配给通过new Matrix
创建的对象,因此对其进行调用将为其调用的矩阵实例返回新的MatrixIterator
。
更多on MDN