为什么我们同时需要迭代和迭代器概念?

问题描述:

在ECMAScript6中,迭代器是一个对象使用 next()方法返回一个具有两个属性的对象: {value,done} .例如:

In ECMAScript6 an iterator is an object with a next() method that returns an object with two properties: {value, done}. E.g.:

function createIterator(ra) {
    let i = 0;
    return {
        next() {
            if (i < ra.length)
                return {value: ra[i++],
                        done: false};
            else
                return {value: undefined,
                        done: true};
        }
    };
}

创建了迭代器后,发现它本身并没有太大用处,因为没有内置语法可利用迭代器.相反,必须执行以下操作:

Having created an iterator one finds it is not very useful in its own right as there's no built-in syntax to take advantage of an iterator. Instead, one has to do things like:

    const it = createIterator(['a', 'b', 'c']);
    while (true) {
        const o = it.next();
        if (o.done)
            break;
        else
            console.log(o.value);
    }

另一方面,"p>可迭代"是具有 Symbol.iterator 属性的对象,该对象必须是返回迭代器的无参数函数:

"Iterable" on the other hand is an object with a Symbol.iterator property that has to be a no-argument function that returns an iterator:

function createIterable(ra) {
    let it = createIterator(ra);
    return {
        [Symbol.iterator]() {return it;}
    };
}

...,当我们创建一个可迭代对象时,我们终于可以使用 for 语法:

... and when we create an iterable we are finally able to use the for of syntax:

for (let v of createIterable(['a', 'b', 'c']))
    console.log(v);

看上面的代码,不容易感觉到迭代器"上可迭代"对象的增加值.那么,为什么Javascript需要Iterable和Iterator这两个单独的概念?顺便说一句,这也是 Java所做的,因此必须有一些与语言无关的原因,拥有这些是一个好主意两个不同的概念.

Looking at the above code the added value of the "iterable" object over the "iterator" is not easily perceived. So why does Javascript need these two separate concepts of iterable and iterator? BTW this is what Java does as well so there must be some language-independent reason why it is a good idea to have these two distinct concepts.

从概念上讲,实现迭代器"接口的对象只是封装了迭代操作的当前状态.一旦迭代器被消耗( it.done === true ),就无法重复使用.

Conceptually, the object that implements the "iterator" interface just encapsulates the current state of an iteration operation. Once that iterator has been consumed (it.done === true) it cannot be re-used.

可迭代"对象的 [Symbol.iterator]()函数每次调用时都会返回 new 迭代器.

The [Symbol.iterator]() function of an "iterable" object returns a new iterator each time it's invoked.

在这方面,请警惕OP的功能可能存在缺陷,因为由他的 createIterable 函数创建的对象仅允许一次性调用其 Symbol.iterator 代码>功能.如果返回的对象被传递给多个 for..of 操作,则将失败.理想情况下,它应显示为:

In that respect, be wary of the OP's function which is potentially flawed since the object created by his createIterable function only allows for a one-off call to its Symbol.iterator function. It would fail if the object returned was passed to more than one for .. of operation. Ideally it should read:

function createIterable(ra) {
    return {
        [Symbol.iterator]() {
             return createIterator(ra);
        }
    }
}