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所做的,因此必须有一些与语言无关的原因,为什么拥有这两个截然不同的概念是一个好主意。
从概念上讲,实现“迭代器”接口的对象只是封装了迭代操作的当前状态。一旦该迭代器被消耗(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)