请描述一下这段代码中的工作原理Symbol.iterator

时间:2019-05-29 15:46:18

标签: javascript

我目前正在阅读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);
};

1 个答案:

答案 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