迭代器是被设计专用于迭代的对象,带有特定接口。所有的迭代器对象都有next方法,会返回一个结果对象。该结果对象有两个属性:对应下一个值的value,以及一个布尔类型的done,其值为true时表示没有更多对值可供使用。
- //es5创建迭代器
- function createIterator(items) {
- var i = 0;
- return {
- next: function() {
- var done = (i >= items.length);
- var value = !done ? items[i++] : "undefined";
- return {
- done: done,
- value: value
- }
- }
- }
- }
- var iterator = createIterator([1, 2, 3]);
- console.log(iterator.next()); //{done:false,value:1}
- console.log(iterator.next()); //{done:false,value:2}
- console.log(iterator.next()); //{done:false,value:3}
- console.log(iterator.next()); //{done:true,value:"undefined"}
- console.log(iterator.next()); //{done:true,value:"undefined"}
生成器是一个能返回迭代器的函数。生成器函数由放在function关键字之后的一个星号(*)来表示,并使用新的yield关键字(指定迭代器在被next()方法调用时应当按顺序返回的值。)。
- function * createIterator() {
- yield 1;
- yield 2;
- yield 3;
- }
- var iterator = createIterator();
- console.log(iterator.next()); //{done:false,value:1}
- console.log(iterator.next()); //{done:false,value:2}
- console.log(iterator.next()); //{done:false,value:3}
- console.log(iterator.next()); //{done:true,value:undefined}
- console.log(iterator.next()); //{done:true,value:undefined}
生成器最有意思的方面可能就是它们会在每个yield语句后停止执行。
- //yield语句在for循环中的使用
- function * createIterator(items) {
- for (let i = 0, len = items.length; i < len; i++) {
- yield items[i];
- }
- }
- var iterator = createIterator([1, 2, 3]);
- console.log(iterator.next()); //{done:false,value:1}
- console.log(iterator.next()); //{done:false,value:2}
- console.log(iterator.next()); //{done:false,value:3}
- console.log(iterator.next()); //{done:true,value:undefined}
- console.log(iterator.next()); //{done:true,value:undefined}
yield只能用于生成器内部,用于其他任何位置都会报错,即使在生成器内部的函数中也不行。因为yield无法穿越函数边界。从这点上来说,yield与return非常相似。
- function * createIterator(items) {
- items.forEach(function(item) {
- yield item + 1; //语法错误
- })
- }
你可以使用函数表达式来创建一个生成器,只需要在function关键字与圆括号之间使用一个星号(*)即可。
- var o = {
- *createIterator(items){
- for (let i = 0, len = items.length; i < len; i++) {
- yield items[i];
- }
- }
- }
可迭代对象被设计用于与es新增的for-of循环配合使用。
for-of循环在循环每次执行时会调用可迭代对象的next()方法,并将结果对象的value储存在一个变量上。循环过程会持续到结果对象的done属性编程true为止。
- let values = [1, 2, 3];
- for (let num of values) {
- console.log(num);
- }
- //输出内容为
- 1,2,3
- let set = new Set([1, 3, 3, 2, 4, 5, 1, 3]);
- for (let val of set) {
- console.log(val);
- }
- //输出内容为
- 1,3,2,4,5
- let map = new Map();
- map.set("name", "cc");
- map.set("age", 26);
- for (let val of map) {
- console.log(val);
- }
- //输出内容为
- ["name","nicolas"]
- ["age",52]
你可以使用Symbo.iterator来访问对象上的默认迭代器。
- let values = [1, 2, 3];
- var iterator = values[Symbol.iterator]();
- console.log(iterator.next());//{value:1,done:false}
- console.log(iterator.next());//{value:2,done:false}
- console.log(iterator.next());//{value:3,done:false}
- console.log(iterator.next());//{value:undefined,done:true}
ES6具有三种集合对象类型:数组、Map和Set。这三种类型都拥有如下迭代器:
- let colors = ["red", "green", "blue"];
- let set = new Set([1234, 5678, 9012]);
- let map = new Map();
- map.set("title", "unde");
- map.set("format", "ebook");
- //entries
- for (let entry of colors.entries()) {
- console.log(entry);
- }
- for (let entry of set.entries()) {
- console.log(entry);
- }
- for (let entry of map.entries()) {
- console.log(entry);
- }
- //values
- for (let value of colors) {
- console.log(value);
- }
- for (let value of set.values()) {
- console.log(value);
- }
- for (let value of map.values()) {
- console.log(value);
- }
- //keys
- for (let key of colors.keys()) {
- console.log(key);
- }
- for (let key of set.keys()) {
- console.log(key);
- }
- for (let key of map.keys()) {
- console.log(key);
- }
- let message = "A B";
- for (let s of message) {
- console.log(s);
- }
- //输出内容为
- A
- (BLANK)
- (BLANK)
- B
- let p = document.getElementsByTagName("p");
- for (let c of p) {
- console.log(c.className);
- }
- function * createIterator() {
- let first = yield 1;
- let second = yield first + 2;
- yield second + 3;
- }
- let iterator = createIterator();
- console.log(iterator.next()); //1
- console.log(iterator.next(4)); //6
- console.log(iterator.next(5)); //8
在包含赋值操作的第一个yield语句中,表达式右侧再第一次调用next()时被计算,而表达式左侧则在第二次调用next()方法时,并在生成器函数执行之前被计算。
- function * createNumI() {
- yield 1;
- yield 2;
- }
- function * createColI() {
- yield "red";
- yield "green";
- }
- function * createComb() {
- yield * createNumI();
- yield * createColI();
- yield true;
- }
- let iterator = createComb();
- console.log(iterator.next()); //{value:1,done:false}
- console.log(iterator.next()); //{value:2,done:false}
- console.log(iterator.next()); //{value:"red",done:false}
- console.log(iterator.next()); //{value:"green",done:false}
- console.log(iterator.next()); //{value:true,done:false}
- console.log(iterator.next()); //{value:undefined,done:false}
来源: http://www.cnblogs.com/xzsty/p/7866835.html