zoukankan      html  css  js  c++  java
  • 3/4 关于JavaScript迭代器

    写在前面

      仅供自用

      ...


    Iterable 接口

      在我的理解里面,如果数据结构实现了 Iterable 接口 那么 这个数据结构就是可迭代对象

      当然实现这个的方法 就是 写一个迭代器工厂函数 [Symbol.iterator] 来生成一个含有 next(){}  和 return(){} 两个属性方法的对象 也就是 迭代器

    Iterator 迭代器

      next()

      迭代器 进行对 可迭代对象的消费 ( 我的理解就是 通过 next() 来一步一步把 可迭代对象 ( 实现 Iterable 接口的 数据结构 ) 榨干 )

    let arr_3 = [1,2,3];
    let iter = arr_3[Symbol.iterator](); // 记得加一个() 立即执行函数 得到返回的一个 迭代器 iterator 
    console.log(iter); // 可以验证一下 得到  Array Iterator {}
    console.log(iter.next()); // {value: 1, done: false}
    console.log(iter.next()); // {value: 2, done: false}
    console.log(iter.next()); // {value: 3, done: false}
    console.log(iter.next()); // {value: undefined, done: true} 表示读完了 done为true的嘛

      return()

      return() 是当遇到了 break continue 或者是 throw 提前结束 迭代器 操作的 属性

    class Test {
        // 构造函数
        constructor(limit){
            this.limit = limit;
        }
        // 通过闭包 实现 Iteratable 接口 [Symbol.iterator] 函数就是一个 迭代器工厂 返回一个迭代器对象 里面有 next() 和 return() 方法
        [Symbol.iterator](){
            let limit = this.limit;
            let start = 0;
            // 返回 一个对象 其中有属性next() ( 我们必须实现这个方法才是实现了 Iterable 接口)
            return{
                // 不断调用 next() 实现迭代
                next(){
                    if(start < limit){
                        return {done:false,value:start++}; // 下次增加 第一次为 0 扩展为 0 1 2 3
                        // return {done:false,value:++start}; // 本次增加 第一次为 1 如果扩展则为 1 2 3 4
                    }
                    else{
                        return {done:true,value:undefined};
                    }
                },
                // 当遇到 break continue throw 提前退出 调用的属性方法 应当返回一个 {done:true}
                return(){
                    console.log("提前结束");
                    return { done:true };
                }
            }
        }
    }
    
    // 实例化 一个 test
    let test1 = new Test(4);
    // 扩展运算符测试 是否正常 
    console.log(...test1); // 0 1 2 3 
    // 通过 for-of 测试 提前结束
    for (const iterator of test1) {
        if(iterator === 2){
            break;
        }
        console.log(iterator);
    } // 0 1 提前结束

      当然 有一些可迭代对象 没办法重启 (一般来说叫关闭)迭代器状态 比如数组

      这个时候return形如虚设...( 这个是针对可迭代对象的迭代器而言,可迭代对象无法直接对符号 [Symbol.iterator] 进行更改 )

    console.group(4);
    let arr_4 = [0,1,2,3,4];
    let iteratorOfArr4 = arr_4[Symbol.iterator]();
    
    // 开始重新覆盖 迭代器的 return(){}
    iteratorOfArr4.return = function(){
        console.log("提前结束");
        return {done:true};
    }
    console.log(iteratorOfArr4); // 可以看到 加入了 return(){}
    
    // 因为 iteratorOfArr4 相当于实现了 iterable 接口 而且关联了一个可迭代对象 arr_4 所以自己也是一个可迭代对象
    // 但是这里 ta 自己不能 控制关闭迭代器状态
    for (const iterator of iteratorOfArr4) {
        console.log(iterator);
        if(iterator == 2){
            break;
        }
    } // 0 1 2 提前结束
    for (const iterator of iteratorOfArr4) {
        console.log(iterator); 
    } // 3 4
    
    // 如果 for-of 用于 arr_4 但是原有的迭代器没有被重新覆盖 只是 iteratorOfArr4 写了
    console.log(arr_4[Symbol.iterator]());  // Array Iterator {}
    arr_4[Symbol.iterator]().return = function(){
        console.log("提前结束");
        return {done:true};
    }
    console.log(arr_4[Symbol.iterator]());  // 可以看到加不进去 因为是 符号 没法改变( 猜想 ) 只能通过 在期望 可迭代对象的地方 用ta自己的迭代器来实现某些操作
    
    for (const iterator of arr_4) {
        console.log(iterator);
        if(iterator == 2){
            break;
        }
    } // 0 1 2 
    for (const iterator of arr_4) {
        console.log(iterator); 
    } // 0 1 2 3 4
    Let it roll
  • 相关阅读:
    Python open() 函数
    python中的多重循环
    网络爬虫构造出URL的列表数据
    js自定义类和对象及继承
    最全的CSS浏览器兼容问题
    大型网站性能优化(页面(HTML)优化的方法)
    element-ui el-table有设置固定列fixed,高度不对的情况
    伊始
    【Object-C】Object-C 的包装类
    【Object-C】处理对象:description 方法、isEqual方法
  • 原文地址:https://www.cnblogs.com/WaterMealone/p/14488061.html
Copyright © 2011-2022 走看看