首页 > 其他分享 >lterator迭代器-Generator生成器

lterator迭代器-Generator生成器

时间:2023-03-06 13:24:52浏览次数:31  
标签:console 迭代 Generator 函数 生成器 lterator next log

什么是迭代器

  •  迭代器iterator,使用户在容器对象(container,例如链表或数组)上遍访的对象,使用该接口无需关心对象的内部实现细节。
    • 他就跟数据库中的光标,迭代器最早出现在1974年设计的CLU编程语言中;
    • 在各种编程语言的实现中,迭代器的实现方式各不相同,但是基本都有迭代器,比如java、python等
  • 迭代器是帮助我们对某个数据结构进行遍历的对象。
  • 在javascript中,迭代器也是一个具体的对象,这个对象需要符合迭代器协议(iterator protocol);
    • 迭代器协议定义了产生一系列值(无论是有限还是无限个)的标准方式;
    • 在JavaScript中这个标准就是一个特定的next方法;
  • nex方法有如下的要求
    • 一个无参数或者一个参数的函数,返回一个应当拥有以下两个属性的对象;
    • done(boolean)
      • 如果迭代器可以产生序列中的下一个值,则为false。
      • 如果迭代器已将序列迭代完毕,则为true.这种情况下,value是可选的,如果它依然存在,即为迭代结束之后的默认返回值。
    • value
      • 迭代器返回的任何JavaScript值,done为true时可省略。
  • 将一个普通对象变成可迭代对象
    • 先实现一个特定的函数:[symbol.iterator]
    • 这个函数需要返回一个迭代器(这个迭代器用于迭代当前的对象)

可迭代对象

  • 可迭代对象和迭代器的概念不同;当一个对象实现了iterble protocol协议时,它就是一个可迭代对象这个对象要求是必须实现iterator方法,在代码中我们使用Synbol.iterator访问该属性;
  • 当一个对象变成一个可以迭代对象的时候,就可以进行某些迭代操作;
  • 比如for..of等操作就是调用它的iterator方法;
  • 原生可迭代对象:string、Array、Map、Set、arguments对象、NodeList集合;

可迭代对象的应用

  • JavaScript中的语法:for...of、展开语法、yield*、解构赋值
  • 创建一些对象时:new Map([lterable])、new WeakMap([iterable])、new WeakSet([itearble]);
  • 一些方法的调用:Promise.all(iterable)、Promise.race(iterable)、Array.form(iterable);

迭代器中断

  • 迭代器在某些情况下会在没有完全迭代的情况下中断
  • 遍历的过程中通过break、return、throw中断了循环操作;
  • 结构赋值没有结构所有的值
  • 这个时候可以监听中断
    •   const obj = {
              name: "小明",
              age: 18,
              skill: "技能",
              [Symbol.iterator]() {
                const key = Object.keys(this);
                let index = 0;
                const iterator = {
                  next() {
                    if (index < key.length) {
                      return { done: false, value: key[index++] };
                    } else {
                      return { done: true };
                    }
                  },
                  return() {
                    //监听函数
                    console.log("停止");
                    return { done: true };
                  },
                };
                return iterator;
              },
            };

生成器

  • 什么是生成器

    • 生成器就是es6中新增的一种函数控制、使用的方案,它可以让我们更加灵活的控制函数什么时候继续执行、暂停执行等。
    • 生成器函数也是一个函数,但是和普通的函数有一些区别:
      • 首先,生成器函数需要在function的后面添加一个符号:*
      • 其次,生成器函数可以通过yield关键字来控制函数的执行流程
      • 最后,生成器函数的返回值是一个(Generator)生成器对象;
        • 需要执行函数内部的代码,需要生成器对象,调用它的next操作
        • 当遇到yield时,就会中断执行。
      • 生成器事实上是一种特殊的迭代器
      • function* a() {
                //生成器函数调用
                console.log(1);
                console.log(2);
                yield; //暂停函数
                console.log(3);
                console.log(4);
                yield 123;//yield后面可以跟值,value的值
                console.log(5);
                console.log(6);
              }
              const arr = a(); //调用生成器函数,返回一个生成器对象
              arr.next(); //调用next方法往下执行
              arr.next(); //继续调用next方法往下执行
              arr.next(); //继续调用next方法往下执行
  • 生成器传递参数-nex函数

    • 函数既然可以暂停来分段执行,那么函数应该是可以传递参数的,那样可以分段来传递参数;
    • 调用nex的时候,可以給他传递参数,那么这个参数会作为上一个yield语句的返回值,第一次传递的时候就跟普通形参一样传递;
    • 也就是说我们为本次的函数代码执行提供了一个值;
  • 生成器提前结束

    • return函数:return函数也是一个可以给生成器函数传递参数的方法
    • return传值后这个生成器函数就会结束,之后调用next不会继续生成值了;
    • throw函数:抛出异常后我们可以在生成器函数在捕获异常;
    • 但是在catch语句中不能继续yield新的值了,但是可以在catch语句外是固态yield继续中断函数的执行。
  • 生成器替代迭代器

    • 对之前代码重构;
    •  1   const arr1 = ["小明", "小红", "小绿"];
       2       const arr2 = [100, 120, 130, 156, 132, 198];
       3       function* nameiterator(arr) {
       4         for (let i = 0; i < arr.length; i++) {
       5           yield arr[i];
       6         }
       7       }
       8       const namesiterator = nameiterator(arr1);//因为生成器的返回值就是迭代器
       9       console.log(namesiterator.next());
      10       console.log(namesiterator.next());
      11       console.log(namesiterator.next());
      12       console.log(namesiterator.next());

       

    • yield*相当于一种yidield的语法糖,只不过会一次的迭代这个可迭代对象,每次迭代其中的一个值;
    •  1       const arr1 = ["小明", "小红", "小绿"];4321`
       2       const arr2 = [100, 120, 130, 156, 132, 198];
       3       function* nameiterator(arr) {
       4         yield* arr;//只要是可以迭代的对象就可以使用语法糖,等于上面的for循环
       5       }
       6       const namesiterator = nameiterator(arr1);
       7       console.log(namesiterator.next());
       8       console.log(namesiterator.next());
       9       console.log(namesiterator.next());
      10       console.log(namesiterator.next());

       

    • yield在类中实现
    •    class person {
              constructor(name, age, skill) {
                this.name = name;
                this.age = age;
                this.skill = skill;
              }
              *[Symbol.iterator]() {
                //在类中使用生成器*需要加在前面
                yield* this.skill;
              }
            }
            const p = new person("李明", 18, [1, 2, 3]);
            console.log(p);
            for (const item of p) {
              console.log(item);
            }

       

标签:console,迭代,Generator,函数,生成器,lterator,next,log
From: https://www.cnblogs.com/ffhyy/p/17182205.html

相关文章