Iterable object(可迭代对象)
为了让对象可迭代(也就让 for..of 可以运行)我们需要为对象添加一个名为 Symbol.iterator 的方法(一个专门用于使对象可迭代的内置 symbol)。
- 当
for..of循环启动时,它会调用这个方法(如果没找到,就会报错)。这个方法必须返回一个 迭代器(iterator) —— 一个有next方法的对象。 - 从此开始,
for..of仅适用于这个被返回的对象。 - 当
for..of循环希望取得下一个数值,它就调用这个对象的next()方法。 next()方法返回的结果的格式必须是{done: Boolean, value: any},当done=true时,表示迭代结束,否则value是下一个值
let range ={from:1, to:5};
// 1. for..of 调用首先会调用这个: range[Symbol.iterator]=function(){// ……它返回迭代器对象(iterator object):// 2. 接下来,for..of 仅与此迭代器一起工作,要求它提供下一个值return{ current:this.from, last:this.to,// 3. next() 在 for..of 的每一轮循环迭代中被调用next(){// 4. 它将会返回 {done:.., value :...} 格式的对象if(this.current <=this.last){return{ done:false, value:this.current++};}else{return{ done:true};}}};};
range自身没有next()方法。- 相反,是通过调用
range[Symbol.iterator]()创建了另一个对象,即所谓的“迭代器”对象,并且它的next会为迭代生成值。 -
因此,迭代器对象和与其进行迭代的对象是分开的。
从技术上说,我们可以将它们合并,并使用
range自身作为迭代器来简化代码
let range ={from:1, to:5,[Symbol.iterator](){this.current =this.from;returnthis; //返回自身},next(){if(this.current <=this.to){return{ done:false, value:this.current++};}else{return{ done:true};}}};for(let num of range){alert(num);// 1, 然后是 2, 3, 4, 5}
let range ={from:1, to:5};// 1. for..of 调用首先会调用这个: range[Symbol.iterator]=function(){// ……它返回迭代器对象(iterator object):// 2. 接下来,for..of 仅与此迭代器一起工作,要求它提供下一个值return{ current:this.from, last:this.to,// 3. next() 在 for..of 的每一轮循环迭代中被调用next(){// 4. 它将会返回 {done:.., value :...} 格式的对象if(this.current <=this.last){return{ done:false, value:this.current++};}else{return{ done:true};}}};};// 现在它可以运行了!for(let num of range){alert(num);// 1, 然后是 2, 3, 4, 5}

浙公网安备 33010602011771号