这个问题有很多动态的部分,但是我将从我的第一个误解开始。
上下文:Iterator
被定义为实现next()
方法的对象,下面我的两个示例都具有这种方法。区别在于,我使用next()
方法创建对象的方式有所不同。在第一个示例中,我正在创建一个函数,该函数返回包含next()
方法的Object。然后,我为该函数分配一个变量,因此,如果我没有记错的话,我实际上是使用预定义的函数动态地制作一个对象。
var letters = ["a","b","c"];
function createIterator(array) {
var i = 0;
return { //return an Object with a next() method
next: function(){
i < array.length ? //if statement
{value: array[i++], done: false}:
{value: undefined, done: true};
}
}
}
var myIterator = createIterator(letters);
console.log(myIterator.next()) //{value: a, done: false}
console.log(myIterator.next()) //{value: b, done: false}
console.log(myIterator.next()) //{value: c, done: false}
console.log(myIterator.next()) //{value: undefined, done: true}
因此,通过将createIterator
函数放入变量myIterator
内,每次运行next()
函数时,都会得到传递的数组中的下一个元素。
好的,我想。如果我只是使对象不具有功能怎么办?
var literal = {
letters: ["a", "b", "c"],
next: function(){ //same next function as before
var i = 0;
i < this.letters.length ?
{value: this.letters[i++], done: false}:
{value: undefined, done: true};
}
}
console.log(literal.next()) //{value: a, done: false}
console.log(literal.next()) //{value: a, done: false}
console.log(literal.next()) //{value: a, done: false}
console.log(literal.next()) //{value: a, done: false}
我认为这是由于我对如何使用不同的创建对象的方式调用next()
方法的误解。可能有范围,但我真的不确定。
答案 0 :(得分:1)
在第一个示例中,i
被捕获在一个闭包中,因此可以正常工作。在第二个示例中,每次调用该函数时,i
都会被创建。您可以将其设为对象的属性:
var literal = {
letters: ["a", "b", "c"],
i: 0,
next: function(){ //same next function as before
return this.i < this.letters.length ?
{value: this.letters[this.i++], done: false}:
{value: undefined, done: true};
}
}
console.log(literal.next())
console.log(literal.next())
console.log(literal.next())
console.log(literal.next())
当然,您也可以以在其他上下文中将其用作迭代器的方式来实现它,并且更为简单:
var G = {
letters: ["a", "b", "c"],
[Symbol.iterator]: function*(){
yield *this.letters
}
}
// now the object works as an iterable:
console.log([...G])
// or
let iter = G[Symbol.iterator]()
console.log(iter.next())
console.log(iter.next())
console.log(iter.next())
console.log(iter.next())