迭代器与生成器

迭代器

1.迭代:是从一个数据集合中按照一定的顺序,不断取出数据的过程
2.迭代和遍历的区别?
迭代强调依次取出,不能确定可以取出多少个值,也不能保证把数据取完
遍历必须保证数据的长度,不断地全部取出
3.迭代模式:是一种便臣设计模式,用于统一迭代的过程,并且规范迭代器的格式
4.迭代器:把迭代过程封装起来,(能取出下一个数据,可以判断是否有下一个数据)
js中:如果规定一个对象有next方法,并返回一个对象,就认为这个对象是迭代器

const obj={
	next(){
		return {
			value:data,//数据
			done:boolean//判断是否有后续数据
		}
	}
}

封装一个迭代器

        const arr = [1,2,3,4]
        function createIterator(arr){
            let i = 0
            return {
                next(){
                    var result = {
                        value : arr[i],
                        done : i >= arr.length
                    }
                    i ++;
                    return result;
                }
            }
        }
        const iter = createIterator(arr)
        /*
        输出结果
        iter.next()
		{value: 1, done: false}
		iter.next()
		{value: 2, done: false}
		iter.next()
		{value: 3, done: false}
		iter.next()
		{value: 4, done: false}
		iter.next()
		{value: undefined, done: true}
		*/

在es6中如果对象具有知名符号Symbol.iterator,则表示该对象可以迭代
在es6中如果对象具有知名符号属性Symbol.iterator,则表示该对象可以迭代
const iterator = arrSymbol.iterator;//es6之后,数组可以直接创建迭代对象
这里需要注意直接使用数组的方法迭代需要用值接收一下即

const arr = [1, 2, 3, 4]
const iterator = arr[Symbol.iterator]()//能正常输出,
//如直接用arr[Symbol.iterator]().next()则会出现如下问题
//控制台输出内容
/*
iterator.next()
Object { value: 1, done: false }

iterator.next()
Object { value: 2, done: false }

iterator.next()
Object { value: 3, done: false }

iterator.next()
Object { value: 4, done: false }

arr[Symbol.iterator]().next()
Object { value: 1, done: false }

arr[Symbol.iterator]().next()
Object { value: 1, done: false }

arr[Symbol.iterator]().next()
Object { value: 1, done: false }

arr
Array(4) [ 1, 2, 3, 4 ]
大致原因为es6数组迭代方法形成了闭包,演示方法如下
*/
		function text() {
            let a = Math.random()
            return function() {
                console.log(a)
            }
        }
        const demo = text()//执行后的text()赋值给demo此时的demo为内部函数体
        demo();//0.45445667792917444//因为a随机数已经生成,除再次调用会重新赋值,就不会变化
        demo();//0.45445667792917444//所以三个a相等
        demo();//0.45445667792917444
        text()();//0.6320860615689315//因为每次调用都是执行text()函数后再执行内部函数
        text()();//0.004725499087028573//所以a每次值不同
        text()();//0.19021527574564823

es6新增for of循环: for of 循环遍历、就是专门针对可迭代对象的,不是可迭代对象不能使用 forof循环(使用方法于for in 一样)
obj对象的原型上没有知名符号属性Symbol.iterator

生成器

生成器既是一个迭代器,同时也是一个可迭代对象

function* test() {//*写在函数名旁边表示这个函数为一个生成器
            console.log(123)
            yield 1;
            console.log(456)
            yield 2;
            yield 3;
            return 4; //return会作为最后的返回对象
        }
        const generator = test() //生成了一个生成器而已,生成器中的代码并不会执行
            // 生成器中关键字 yield  只能在函数内部使用,表示产生一个迭代数据
            // 每一次调用生成器中的next方法,会将生成器函数运行到下一个yield关键字的位置
        // 如果生成器函数中有多行语句但没有yeild,则next方法全部执行完
        // 如果想控制生成器函数中代码输出则可以使用yeild
        //使用next方法后会返回一个对象,这个对象就是迭代对象,对象中的value值就是yield后面的值
        console.log(generator.next()) //123 Object { value: 1, done: false }
        console.log(generator.next())//456  Object { value: 2, done: false }
        console.log(generator.next())//789  Object { value: 3, done: false }
        console.log(generator.next())//Object { value: 4, done: true }


// 1.生成器有返回值,出现在最后一次的done为true的value
        // 2.调用生成器中的next方法时,可以传递参数,传递的参数可以交给yeild表达式的返回值
        // 3.第一次去调用函数时,传递的参数是没有任何含义的
        function *test(){
            let info = yield 1;
            console.log(info)
            info = yield 2 + info;
            console.log(info) 
            return 10;
        }
        const generator = test()
//控制台输出
/*
generator.next(9)
Object { value: 1, done: false }

generator.next(9)
9 12.html:15:21
Object { value: 11, done: false }

generator.next(9)
9 12.html:17:21
Object { value: 10, done: true }
*/

生成器api
generator.return() 直接提前结束
generator.throw(new Error(“qwe”))可以在生成器产生一个错误,抛出到对应的行中去

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值