一、迭代器(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
。如果value
和done
一起出现,则它就是迭代器的返回值。
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