js如何创建可迭代对象

创建迭代器

  1. 如何设计一个迭代器

  迭代器的本身是一个对象,这个对象有netx()方法返回结果对象,这个结果对象有下一个返回值value、迭代器完成布尔值done,模拟创建一个简单迭代器:

    function createIterator(items){
        let i = 0;
        return{
            next(){
                let done = (i>=items.length);
                let value = !done ? items[i++] : undefined;
                return{
                    done,
                    value
                }
            }
        }
    }
    let arrayIterator = createIterator([1,2,3])
    console.log(arrayIterator.next());
    console.log(arrayIterator.next());
    console.log(arrayIterator.next());
    console.log(arrayIterator.next());

在这里插入图片描述
每次调用迭代器的next()都会返回下一个对象,直到数据被用尽。
ES6中迭代器的编写过程类似,但引入了生成器对象,更简单的创建迭代器对象。
2. 创建迭代器

ES6封装了一个生成器(generator)用来创建迭代器。先然生成器是返回迭代器的函数,这个函数通过function后的*号表示,并使用新的内部专用关键字yield指定迭代器next()方法的返回值
用ES6生成器创建一个迭代器:

    function *createIterator(){
        yield 123;
        yield "mgd"
    }
    let someIterator = createIterator()

    console.log(someIterator.next()); //{value: 123, done: false}
    console.log(someIterator.next()); //{value: "mgd", done: false}
    console.log(someIterator.next()); //{value: undefined, done: true}

使用yield关键字可以返回任意值或者表达式,可以给迭代器批量添加元素:

    function *createIterator(items){
        for(let i in items){
            yield items[i];
        }
    }

    let someIterator = createIterator([123,'mge']);

    console.log(someIterator.next()); //{value: 123, done: false}
    console.log(someIterator.next()); //{value: "mge", done: false}
    console.log(someIterator.next()); //{value: undefined, done: true}

由于生成器本身是函数,所以可添加到对象中,使用方式如下:

    let obj = {
        *createIterator(items){
            for(let i in items){
                yield items[i]
            }
        }   
    }
    let someIterator = obj.createIterator([123,'mgd']);
    console.log(someIterator.next()); //{value: 123, done: false}
    console.log(someIterator.next()); //{value: "mgd", done: false}
    console.log(someIterator.next()); //{value: undefined, done: true}

  生成器函数的特点是:当执行完一句yield语句后函数会自动停止执行,再次调用迭代器的next()方法才会继续执行下一个yield语句。
  这种自动中止函数执行的能力衍生出很多高级用法,并提供了async/await语法糖。

可迭代对象是个啥

  1. ES6中常用的集合对象(数组、Set、Map集合)和字符串都是可迭代对象
    这些对象都有默认的迭代器和Symbol.iterator属性。
  2. 通过生成器创建的迭代器也可以是可迭代对象
    生成器默认会为Symbol.iterator属性赋值。

1. Symbol.iterator

可迭代对象具有Symbol.iterator属性,即具有Symbol.iterator属性的对象都有默认迭代器。
  我们可以用Symbol.iterator来访问对象的默认迭代器,例如对于一个数组:

    let list = [1,2,3]
    let iterator = list[Symbol.iterator]();
    console.log(iterator.next()); 
    console.log(iterator.next());
    console.log(iterator.next());
    console.log(iterator.next());

在这里插入图片描述
  显然数组、Set/Map集合、字符串都是可迭代对象,而WeakSet/WeakMap集合(弱引用集合)是不可迭代的。

2. 创建可迭代对象

默认情况下,自定义的对象都是不可迭代的
通过生成器创建的迭代器也是一种可迭代对象,生成器会默认为Symbol.iterator属性赋值

    let collection = {
        items:[1,2,3],
        *[Symbol.iterator](){
            for(let i of this.items){
                yield i
            }
        }
    }
    const isIterator = obj => obj != null && typeof obj[Symbol.iterator] === 'function';
    console.log(isIterator(collection)); //true 
    for(let item of collection){
        console.log(item); //1 2 3
    }

数组items是可迭代对象,collection 对象通过给Symbol.iterator属性赋值也成为可迭代对象。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值