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

Mar*_*tus 5 javascript ecmascript-6

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

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

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

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

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

function createIterable(ra) {
    let it = createIterator(ra);
    return {
        [Symbol.iterator]() {return it;}
    };
}
Run Code Online (Sandbox Code Playgroud)

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

for (let v of createIterable(['a', 'b', 'c']))
    console.log(v);
Run Code Online (Sandbox Code Playgroud)

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

Aln*_*tak 3

从概念上讲,实现“迭代器”接口的对象只是封装了迭代操作的当前状态。一旦该迭代器被消耗(it.done === true),它就不能被重新使用。

[Symbol.iterator]()“可迭代”对象的函数每次被调用时都会返回一个新的迭代器

在这方面,请警惕 OP 的函数,该函数可能存在缺陷,因为由其createIterable函数创建的对象只允许一次性调用其Symbol.iterator函数。如果返回的对象传递给多个for .. of操作,则会失败。理想情况下,它应该是这样的:

function createIterable(ra) {
    return {
        [Symbol.iterator]() {
             return createIterator(ra);
        }
    }
}
Run Code Online (Sandbox Code Playgroud)