前端中迭代器的理解和手动封装一个迭代器

前端中迭代器的理解和手动封装一个迭代器

1.什么是迭代器?

       迭代器就是为了实现对不同集合进行统一遍历操作的一种机制。它本身就是实现了一套迭代协议。
       迭代协议:规定了迭代与实现的逻辑。

可能很多同学看着字面的意思还是很迷惑,啥玩意?别着急,咱们一步步的撸下去。

2.for-of 循环

  2.1   针对数组的for-in 循环

         回顾下for-in 这里直接上代码了;

         

let arr = ['a','b','c','d']
  for(let attr in arr){
       console.log(attr)  
  }

这里面我们可以看出来输出的是key的值,也就是数组的下标;

2.2  针对数组的for of循环

    

let arr = ['a', 'b', 'c', 'd']
        for (let val of arr) {
            console.log(val)
        }

 

  通过for of 我们可以看到输出的是对应的value的值。

2.3 针对对象的for in和for of循环。

  

let obj = {
   a: 'a',
   b: 'b',
   c: 'c'
  }
 for (let attr in obj) {
    console.log(attr, '这是for in循环对象')
}
 for (let val of obj) {
    console.log(val, '这是for of循环对象')
}

此时我们可以看到for in循环对象没问题,但是for of的时候报错,提示这个对象obj是不可迭代的。我们分别在控制台输出arr和obj分别看下,我们可以发现arr有Symbol.iterator方法,但是obj没有。

3.实现一个迭代器

    我们要实现一个可迭代对象,只需要给它实现【Symbol.iterator】方法,而迭代器的实现过程就是迭代协议。下面我们就来手撸一个迭代器。

 let obi  = {
            a: 1,
            b: 2,
            c: 3
        };
     obj[Symbol.iterator] = function(){
            return {}
        }
     for(let val of obj){
         
     }

此时我们运行下看看结果如何;

此时我们会发现这个对象缺少一个function。写迭代器一定要有一个next()方法,在next()里面必须有返回值;

let obj  = {
            a: 1,
            b: 2,
            c: 3
        };
        obj[Symbol.iterator] = function(){
            return {
               next(){
                  return {
                      done: false   //done表示迭代是否完成 fasle 代表否
                  }
                }
            }
        }
     for(let val of obj){

     }

此时在运行下,发现没有报错了,但是一直在执行,进入了一个死循环,舒服了。

下面我们来定义下规则,也就是迭代协议,就是你需要让它根据什么循环,就让它根据你的规定来循环。

        let obj  = {
            a: 1,
            b: 2,
            c: 3
        };
        obj[Symbol.iterator] = function(){
            // 迭代协议 
            let values = Object.values(obj)
            let index = 0;
            console.log(values)
            return {
               next(){
                 if(index>= values.length){
                     //表示循环完成
                     return {
                        // value: values[index++]  循环完成
                         done: true
                     }
                 }else{
                     return {
                         done: false,
                         value: values[index++]
                     }
                 }
                }
            }
        }
     for(let val of obj){
         console.log(val)
     }

此时执行就会发现,这个对象变成了可迭代对象。

我们可以模拟下它执行的过程。这里的代码我稍微修改下,为了测试它的执行过程;

 let obj  = {
            a: 1,
            b: 2,
            c: 3
        };
        obj[Symbol.iterator] = function(){
            // 迭代协议 
            let values = Object.values(obj)
            let index = 0;
            return {
               next(){
                 if(index>= values.length){
                     //表示循环完成
                     return {
                        // value: values[index++]  循环完成
                         done: true
                     }
                 }else{
                     return {
                         done: false,
                         value: values[index++]
                     }
                 }
                }
            }
        }
    let values = obj[Symbol.iterator]();
    console.log(values.next())
    console.log(values.next())
    console.log(values.next())
    console.log(values.next())
    //  for(let val of obj){
    //      console.log(val)
    //  }

执行的结果:

到这我们就算实现了一个迭代器,for of就是相当于一直帮我们next()来执行这个迭代器。其中的迭代协议使我们自己定义的,现在只能输出value的值,那么我们可以让它同时输出key 和valule吗? 当然可以。

        let obj  = {
            a: 1,
            b: 2,
            c: 3
        };
        obj[Symbol.iterator] = function(){
            // 迭代协议 
            let keys = Object.keys(obj)
            let index = 0;
            return {
               next(){
                 if(index>= keys.length){
                     //表示循环完成
                     return {
                        // value: keys[index++]  循环完成
                         done: true
                     }
                 }else{
                     return {
                         done: false,
                         value: {
                             key: keys[index],
                             value: obj[keys[index++]]   //++是为了方便next时拿到下一项
                         }
                     }
                 }
                }
            }
        }
    let values = obj[Symbol.iterator]();
     for(let val of obj){
         console.log(val)
     }

输出一下看看效果:

到这里,咱们的迭代器已经实现了,主要就是通过迭代协议来给对象封装一个Symbol.iterator方法,从而实现对象迭代的效果。下一篇我们将通过generator函数来实现封装一个async await异步执行方法。

 

 

  • 5
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值