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
网友评论