一、迭代器(Iterator)

在 JavaScript 中,迭代器是一个对象,它定义一个序列,并在终止时可能附带一个返回值。更具体地说,迭代器是通过使用next () 方法实现了迭代器协议的任何一个对象,该方法返回具有两个属性的对象:value , done

一旦创建,迭代器对象可以通过重复调用 next()显式地迭代。迭代一个迭代器被称为消耗了这个迭代器,因为它通常只能执行一次。在产生终止值之后,对 next()的额外调用应该继续返回{done:true}

1、迭代器本质

迭代器对象本质上,就是一个指针对象。通过指针对象的next(), 用来移动指针。

ES6 规定,默认的 Iterator 接口部署在数据结构的Symbol.iterator属性上;或者说,一个数据结构只要有Symbol.iterator属性,就认为是可遍历的。

2、可迭代协议

实现 Iterable 接口(可迭代协议)要求同时具备两种能力:支持迭代的自我识别能力和创建实现Iterator 接口的对象的能力。在 ECMAScript 中,这意味着必须暴露一个属性作为“默认迭代器”,而且这个属性必须使用特殊的 Symbol.iterator 作为键。这个默认迭代器属性必须引用一个迭代器工厂函数,调用这个工厂函数必须返回一个新迭代器。
字符串、数组、映射、集合、arguments 对象、NodeList 等 DOM 集合类型,这些内置类型都实现了 Iterable 接口。

3、next()方法返回的具有两个属性的对象:

1)value

迭代序列的下一个值。迭代器返回的任何 JavaScript 值。done 为 true 时可省略

2)done

如果已经迭代到序列中的最后一个值,则它为true。如果valuedone一起出现,则它就是迭代器的返回值。

4、实现Iterator接口的原生对象

  • Array
  • Map
  • Set
  • String
  • TypedArray
  • 函数的 arguments 对象

二、生成器

生成器是一种特殊的函数,它可以在执行过程中暂停,并返回一个迭代器对象。生成器函数通过function*语法来定义,在函数体内使用yield语句可以暂停函数执行,并将值返回给调用方。调用方可以通过迭代器对象来恢复生成器函数的执行,并在下一个yield语句处继续执行。

生成器函数返回的迭代器对象和普通迭代器对象类似,都有一个next()方法,可以用来获取生成器函数中使用yield语句返回的值。但是,生成器函数可以在执行过程中多次返回值,并且可以在每次返回值之间执行一些逻辑操作,这使得生成器函数比普通迭代器更加灵活。

生成器函数与和普通的函数的区别:

1、生成器函数需要在function的后面加一个符号:*

2、生成器函数可以通过yield关键字来控制函数的执行流程:

3、生成器函数的返回值是一个Generator(生成器):

4、生成器事实上是一种特殊的迭代器

三、实例机器代码执行过程

示例代码:

// 生成器函数(Generator)//允许你定义一个非连续执行的函数作为迭代算法。生成器函数使用 function* 语法编写。function* text(num){let x=6*(yield num+1)console.log(x) // 30let y=yield x/3console.log(x,y)// 30 8let z=yield y+5console.log(x,y,z) // 30 8 2return x+y+z+num}let n=text(3)console.log(n.next())//{value:4, done:false}console.log(n.next(5)) //{value:10,done:false}console.log(n.next(8)) //{value:13,done:false}console.log(n.next(2)) //{value:43,done:true}

代码执行过程:

1、n=text(3):拿到迭代器,把3赋值给num

2、第一次 n.next(): 函数开始执行,遇到第一个 yield 停下,yield后面 num+1 作为 n.next() 的返 回值中的value 属性值,故value=4

3、第二次 n.next(5):函数开始执行,将5赋值给第一个 yield 整体,故 x=30;遇到第二个 yield 停下,将 yield 后面 x/3 作为 n.next(5) 的返回值中的 value 属性值,故 value=10

4、第三次 n.next(8):函数开始执行,将8赋值给第二个 yield 整体,故 y=8; 遇到第三个 yield 停 下,将 yield 后面 y+5 作为 n.next(8) 的返回值中的 value 属性值,故 value=13

5、第四次 n.next(2):函数开始执行,将2赋值给第三个 yield 整体,故 z=2; 返回 x+y+z+mum 即返回 30+8+2+3,将返回值赋值给 n.next(2) 的返回值中的 value 属性值,故 value=43