迭代器和生成器

这是我参与更文挑战的第1天,活动详情查看: 更文挑战

(一)迭代器

Iterator迭代器就是一个接口方法,它为不同的数据结构提供了一个统一的访问机制;使得数据结构的成员能够按某种次序排列,并逐个被访问。

那么在日常开发中,如何让一个对象成为一个可迭代对象呢?即支持迭代器规范的对象(iterable)
可以给obj 对象添加Symbol.iterator属性,同时在返回的next方法中,添加value和done两个属性。

let obj = {
    0:'d',
    1:'dp',
    2:'f',
    length:4,
    [Symbol.iterator]: function(){
        let index = 0;
        let next = () => {
            return {
                value:this[index],
                done: this.length == ++index
            }
        }
        return {next}
    }
}
console.log([...obj])	
复制代码

输出结果

image.png

value属性返回当前位置的成员,done属性是一个布尔值,表示遍历是否结束,即是否还有必要再一次调用next方法;当done为true时,即遍历完成。既让它成为了一个可迭代对象可以使用扩展运算符。


(二)生成器

生成器是一个极为灵活的结构,拥有在一个函数内暂停和恢复代码执行的能力。

其实Generator函数就是一个普通函数,但是有两个特征,一是,function关键字与函数名之间有一个星号*;二是,函数内部使用yield表达式,定义不同的内部状态。

生成器函数的使用

function* generatorFn(){}

const generatorObject = generatorFn()

console.log(generatorObject ) //generatorFn(<suspended>)
console.log(generatorObject.next())// { value: undefined, done: true }
复制代码

next()方法的返回值类似于迭代器,有一个done属性和一个value属性。函数体为空的生成器函数中间不会停留,调用一次next()就会让生成器到达done:true状态。

value 属性是生成器函数的返回值,默认undefined,可以通过生成器函数的返回值指定:

function* generatorFn(){
	return 'foo'
}

const generatorObject = generatorFn()

console.log(generatorObject ) //generatorFn(<suspended>)
console.log(generatorObject.next())// { value: 'foo', done: true }
复制代码

通过yiled中断执行
yiled 关键字可以让生成器停止和开始执行,也是生成器最有用的地方。生成器函数在遇到yield关键字之前会正常执行,遇到这个关键字之后会停止执行,函数作用域的状态会被保留。停止执行的生成器函数只能通过在生成器对象上调用next()方法来恢复执行。

function* helloWorldGenerator() {
  yield 'hello';
  yield 'world';
  return 'ending';
}

var hw = helloWorldGenerator();
hw.next()
// { value: 'hello', done: false }
hw.next()
// { value: 'world', done: false }
hw.next()
// { value: 'ending', done: true }
hw.next()
// { value: undefined, done: true }
复制代码

调用生成器函数会产生一个生成器对象。生成器对象一开始处于暂停执行(suspended)的状态。与迭代器相似,生成器对象也实现了iterator接口,因此具有next()方法。调用这个方法会让生成器恢复执行。

生成器对象作为可迭代对象
在生成器对象上显式调用next()方法的用处并不大。其实,如果把生成器对象当作可迭代对象,那么使用起来会很方便:

function* generatorFn(){
	yiled 1;
	yiled 2;
	yiled 3;
}
for(const x of generatorFn()){
console.log(x)
}
//1
//2
//3
复制代码
© 版权声明
THE END
喜欢就支持一下吧
点赞0 分享