js 迭代器与生成

2020-10-30  本文已影响0人  Viewwei

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
上一篇下一篇

猜你喜欢

热点阅读