美文网首页
js 迭代器与生成

js 迭代器与生成

作者: Viewwei | 来源:发表于2020-10-30 20:12 被阅读0次

    1 迭代器:循环时迭代器的基础,迭代器可以指定迭代的次数,以及每次迭代要执行什么操作。每次都会在下一次迭代之前完成
    2 可迭代协议
    实现Iterable接口要具备两种能力:1.支持迭代的自我识别能力和创建实现Iterable接口的对象能力。对象一般都有暴露的摩尔嗯迭代器(Symbol.iterable)。字符串 数组 映射 集合 arguments对象 NodeLIst等DOM集合类型
    3 获取对象的迭代器

    let arr = ["foo","bar"]
    let iter = arr[Symbol.iterable]()
    console.log(iter) //ArrayIterator
    console.log(iter.next()) //{done:false,value: 'foo'}
    console.log(iter.next()) //{done:false,value: 'bar'}
    console.log(iter.next()) //{done:true,value: 'undefined'} done为true代表执行结束
    
    class Foo {
        [Symbol.iterator] () {
            return {
                next() {
                    return {done:false,value:'foo'}
                }
            }
        }
    }
    let f = new Foo()
    console.log(f[Symbol.iterator]()) //{ next: [Function: next] }
    

    4 自定义迭代器
    任何实现Iterator接口的对象都可以使用迭代器

    class Counter {
        constructor(limit) {
            this.count =1
            this.limit = limit
        }
        next() {
            if (this.count <= this.limit) {
                return {done:false,value:this.count ++}
            }else {
                return {done:true,value:undefined}
            }
        }
        [Symbol.iterator] () {
            return this
        }
    }
    let c = new Counter(3)
    console.log(c)
    for (let i of c) {
        console.log(i) // 1,2,3
    }
    //因为迭代器已经跑完
    for (let i of c) {
        console.log("o:" +i) //不会执行
    }
    

    为了让一个可迭代对象创建多个迭代器,必须每创建一个迭代器对应一个新计数器。可以把计数器放到闭包中,然后通过闭包返回迭代器

    class Counter {
        constructor(limit) {
            this.limit = limit
        }
        [Symbol.iterator] () {
            let count = 1
          let  limit = this.limit
            return {
                next() {
                    if (count <= limit) {
                        return {done:false,value:count ++}
                    }else {
                        return {done:true,value:undefined}
                    }
                }
            }
        }
    }
    let c = new Counter(3)
    console.log(c)
    for (let i of c) {
        console.log(i)
    }
    for (let i of c) {
        console.log("o:" +i)
    }
    

    5 提前终止迭代器
    for-of循环可以使用break contaion return throw提前退出。

    class Counter {
        constructor(limit) {
            this.limit = limit
        }
        [Symbol.iterator] () {
            let count = 1
          let  limit = this.limit
            return {
                next() {
                    if (count <= limit) {
                        return {done:false,value:count ++}
                    }else {
                        return {done:true,value:undefined}
                    }
                },
                return() {
                    console.log("exxxx")
                    return {done:true}
                }
            }
        }
    }
    let c = new Counter(3)
    console.log(c)
    for (let i of c) {
        console.log(i)
        if (i==2) {
            return //提前结束整个迭代器,导致后面不执行
        }
    }
    for (let i of c) {
        console.log("o:" +i) //不会执行
    }
    

    迭代器提前结束,下次迭代从结束位置开始

    let a = [1,2,3,4,5]
    let inter = a[Symbol.interator]()
    iter.return  = function() {
    return {done:true}
    }
    for(let i of iter) {
    console.log(i)
      if (i>2) {
      break
    }
    }
    //1 ,2
    for(let i of iter) {
    console.log(i)
    
    }
    }
    //3,4
    

    相关文章

      网友评论

          本文标题:js 迭代器与生成

          本文链接:https://www.haomeiwen.com/subject/arzdvktx.html