简单聊聊迭代器与生成器

迭代器是什么❓

迭代器是一种特殊对象,这类特殊对象需要符合*迭代器协议*。这种对象具有以下特点:

  1. 迭代器对象必须有一个next方法;
  2. 每次调用next方法,都会返回一个对象,该对象包含两个属性,一个是value, 表示下一个将要返回的值。另一个是done,他是一个布尔值,用来表示该迭代器是否还有数据可以返回;
  3. 迭代器还会保存一个内部指针指向当前集合中的值;
  4. 每次生成的迭代器对象都是一次性的,只能遍历一次,迭代至最终始终只返回 { value: undefined, done: true };

上Demo:手动实现一个迭代器

function createIterator( arr ){
    var i = 0;
    // 返回一个对象,该对象必须有next方法
    return {
        next : function(){
            var done = ( i >= arr.length );
            var value = !done ? arr[i++] : undefined;
            return {
                done : done,
                value : value
            }
        }
    };
}

var iterator = createIterator( [ 10, 20, 30 ] );
console.log( iterator.next() ); // { done : false, value : 10 }
console.log( iterator.next() ); // { done : false, value : 20 }
console.log( iterator.next() ); // { done : false, value : 30 }
console.log( iterator.next() ); // { done : true, value : undefined }

生成器是什么❓

生成器是一种返回迭代器的函数(生成器也可称为生成器函数),通过function关键字后的星号( * )来表示,函数中会用到新的关键字yield. 。星号( * )可以紧跟function后面,也可以在function后面加个空格。

老规矩,直接上 Demo:

function *createIterator(){
    yield 10;
    yield 20;
    yield 30;
}

var iterator = createIterator();
console.log( iterator.next() ); // { done : false, value : 10 }
console.log( iterator.next() ); // { done : false, value : 20 }
console.log( iterator.next() ); // { done : false, value : 30 }
console.log( iterator.next() ); // { done : true, value : undefined }

通过上面这段程序,你应该看出来了,结果跟我们之前用es5实现的迭代器是差不多的。但是你在这个生成器函数中压根就没有看见next方法,done和value属性。因为生成器函数内部实现了迭代器。

重点要关注下这个 yield 关键字,它有什么特点呢?

  1. 每当执行完一条yield语句,函数就会自动停止执行, 执行完yield 10之后,函数就会自动停止。
  2. 下一次调用next方法,就会执行yield 20,函数又会自动停止。
  3. 下一次调用next方法,就会执行yield 30,函数自动停止。
  4. 下一次在调用,没有可以迭代的元素,value返回undefined。

使用 yield 关键字,需要注意的地方:

  1. yield关键字只能在生成器内部使用,在生成器内部的函数使用也会报错。
// 错误示范1 ❎
function show(){
  yield 10;
}
show();
// 错误示范2 ❎
function *createIterator( arr ){
  for( var i = 0, len = arr.length; i < len; i++ ) {
    return function(){
      yield arr[i];
    }
  }
}
  1. 生成器支持函数表达式的写法,但是不支持箭头函数。
// 错误示范1 ❎
var createIterator = *( arr ) => {
  for( var i = 0, len = arr.length; i < len; i++ ) {
    yield arr[i];
  }
}
// 错误示范2 ❎
var *createIterator = ( arr ) => {
  for( var i = 0, len = arr.length; i < len; i++ ) {
    yield arr[i];
  }
}
  • 4
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值