迭代就是遍历一个东西,不一定要遍历完。
为什么需要迭代器?因为使用循环来迭代不理想,具体有两方面原因:
我们需要的是一种通用迭代方式,能对自己定义的任何对象进行迭代的方法。这个方法就是使用迭代器
这里需要分清三个概念:可迭代对象、迭代器工厂函数、迭代器:
let str = [‘a‘,‘b‘,‘c‘]; // 可迭代对象 console.log(str[Symbol.iterator]) // 打印出迭代器工厂函数 console.log(str[Symbol.iterator()]) // 调用迭代器工厂函数会生成一个迭代器
实现迭代器接口意味着该可迭代对象有个 Symbol.iterator 键(作为默认迭代器属性),它引用一个迭代器工厂函数,调用这个工厂函数必须返回一个新迭代器。JS中实现迭代器接口的对象有 String Array Map Set DOM, 这些对象在如 for - of 等语法下会自动调用迭代器工厂函数创建迭代器,然后调用迭代器的 next 方法,返回一个对象包含 done 和 value:
class Counter{ constructor(limit){ this.limit=limit; } // 这就叫实现了迭代器接口,它返回一个迭代器对象,next是其方法 [Symbol.iterator](){ let count=1, limit=this.limit; return { next(){ if(count<=limit){ return {done:false,value:count++}; // 若迭代还没完 }else{ return {done:true,value:undefined}; // 若迭代结束 } } } } } let counter = new Counter(3); for(let i of counter){console.log(i)} // 1 2 3 for(let i of counter){console.log(i)} // 1 2 3
return() 方法可以用来提前关闭迭代器,当 for-of 结构遇到 break、continue、return 、throw 提前退出:
class Counter{ constructor(limit){ this.limit=limit; } // 这就叫实现了迭代器接口,它返回一个迭代器对象,next是其方法 [Symbol.iterator](){ let count=1, limit=this.limit; return { next(){ if(count<=limit){ return {done:false,value:count++}; }else{ return {done:true,value:undefined}; } }, return(){ console.log(‘提前退出‘); return {done:true}; } } } } let counter = new Counter(3); for(let i of counter){ if(i>2){ break; } console.log(i); } // 1 2 提前退出
如果迭代器没有关闭,还可以继续从上次离开的地方开始迭代:
let a = [1,2,3,4,5]; let iterator = a[Symbol.iterator](); // 返回迭代器 for(let i of iterator){ console.log(i); if(i>2){ break; } } // 1 2 3 for(let i of iterator){ console.log(i); } // 4 5
数组的迭代器是不能关闭的,即使给它增加一个 return 方法也不行。
原文:https://www.cnblogs.com/starboy13/p/14876794.html