什么是迭代器、生成器,如何创建

迭代器

  迭代器是一个特殊的对象,该对象包含一个next方法,每次调用next方法后会返回一个结果对象,结果对象中包含一个value属性和done属性。如果一个对象原型上具有Symbol.interator属性的实现,那么该对象就可以使用for of进行迭代遍历访问。具有内置迭代对象的数据类型有StringArrayMapSet、类数组。
特点:

  1. 所有对象都有一个next()方法
  2. 每次调用next方法,都会返回一个对象,该对象包含valuedone两个属性,value属性表示下一个将要返回的值,done是一个布尔值,用来表示该迭代器是否还有数据可以返回。
  3. 迭代器还会保存一个内部指针指向当前集合中的值。
let arr = [1,2,3];
    function createInterator(arr){
        let index= 0;
        return{
            next:()=>{
                return index < arr.length?{
                    value:arr[index++],
                    done:false
                }:{
                    value:undefined,
                    done:true
                }
            }
        }
    }
    let iterator = createInterator(arr)
    console.log("1=====>",iterator.next());
    console.log("2=====>",iterator.next());
    console.log("3=====>",iterator.next());
    console.log("4=====>",iterator.next());

在这里插入图片描述

生成器

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

    function *createInterator(){
        yield 10;
        yield 20;
        yield 30;
    }
    let iterator = createInterator();
    console.log(iterator.next()); //{value: 10, done: false}
    console.log(iterator.next()); //{value: 20, done: false}
    console.log(iterator.next()); //{value: 30, done: false}
    console.log(iterator.next()); //{value: undefined, done: true}

  在这个生成器函数中没有next()方法,也没有valuedone属性。因为生成器函数内部实现了迭代器。
  yield关键字的特点: 每当执行完一条语句,函数就会自动停止执行
注意:

  1. yield关键字只能在生成器内部使用,在生成器内部的函数使用也会报错
    function show(){
        yield 10
    }
    show() //Uncaught SyntaxError: Unexpected number
    function *createInterator(arr){
        for(let i = 0;i<arr.length;i++){
            return function(){
                yield arr[i]
            }
        }
    }
    let iterator = createInterator([1,2,3]);
    console.log(iterator.next()); //Uncaught SyntaxError: Unexpected identifier
  1. 生成器支持函数表达式的写法,但是不支持箭头函数
let  createIterator = function *( arr ){
    for( let  i = 0;i< arr.length; i++ ) {
        yield arr[i];
    }
}
let  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 } 
//以下方法是错误的
var createIterator = * (arr)=>{
    for( let  i = 0;i< arr.length; i++ ) {
        yield arr[i];
    }
}


var *createIterator= (arr)=>{
    for( let  i = 0;i< arr.length; i++ ) {
        yield arr[i];
    }
}

迭代器的运用

var dream = {a:2,b:3,c:5};
for(var i of dream){
    console.log(i); //dream is not iterable
}

  由于dream是不可迭代的,所以使用for of循环不能遍历

    var dream = {a:2,b:3,c:5};
    
    Object.defineProperty(dream,Symbol.iterator,{
        enumerable:false, //枚举
        writable:false, //可重写
        configurable:true, //可配置
        value:function(){
            var o= this;
            var idx = 0; //索引值
            var ks = Object.keys(o);
            return {
                next:function(){
                    return{
                        value:o[ks[idx++]],
                        done:(idx>ks.length)
                    }
                }
            }
        }
    })
   
    for(var i of dream){
        console.log(i);  //2  3  5
    }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值