1.iterator迭代接口
ES6提供了一种统一的接口机制,以便于遍历不同的数据结构,原有的数组和对象都内置了这个接口,在其原型对象__proto__上即可看到Symbol.iterator,而为了处理ES6新增的数据结构,任何数据结构只要部署 Iterator 接口,就可以完成遍历操作(即依次处理该数据结构的所有成员)。
iterator对象上提供了一个next方法,每次调用则会依次指向其对象的每个对象,done表示遍历是否完成,实际遍历的过程就是内部维护了一个数据指针,一直调用next方法直至遍历完成。
2.for...of循环
ES6 借鉴 C++、Java、C# 和 Python 语言,引入了for...of循环,作为遍历所有数据结构的统一的方法。 换句话说,只要该数据结构具有iterator迭代接口,即可使用for...of进行循环。
const arr = [1,2,3]
for (var item of arr){
console.log(item);
}
// 打印结果
1
2
3
而没有iterator接口的数据结构是无法使用for...of进行遍历的,如
const obj = {
a:'123',
b:'456'
}
for (var item of obj){
console.log(item);
}
//输出报错
TypeError: obj is not iterable
应用场景:在数据与方法高度耦合的时候,如果数据进行更新,遍历其新数据的相应方法可能也要更新,而iterator接口提供了统一的遍历方法
与for...in的区别:
1.for...in遍历得到的是keys,而for...of得到的是values.
2.for...of循环调用遍历器接口,数组的遍历器接口只返回具有数字索引的属性。这一点跟for...in循环也不一样。
3.Generator生成器函数
Generator 函数是一个普通函数,但是有两个特征。一是,function
关键字与函数名之间有一个星号;二是,函数体内部使用yield
表达式,定义不同的内部状态(yield
在英语里的意思就是“产出”)。
function * cloudgaps() {
console.log('123');
return 100
}
const result = cloudgaps()
console.log(result);
//打印结果
Object [Generator] {}
通过函数名前加*可以生成一个generator函数,如果直接调用只会返回一个generator对象,而实际上generator内置了迭代器,通过next才能遍历调用里面的执行语句。函数内执行时,遇到yield就会暂停后面的操作,并将yield后面的值作为属性value返回值。
需要注意的是,yield
表达式后面的表达式,只有当调用next
方法、内部指针指向该语句时才会执行,因此等于为 JavaScript 提供了手动的“惰性求值”(Lazy Evaluation)的语法功能。
function * cloudgaps() {
console.log('123');
yield 1
console.log('456');
yield 2
console.log('789');
yield 3
}
const result = cloudgaps()
console.log(result.next());
console.log(result.next());
console.log(result.next());
//输出结果
123
{ value: 1, done: false }
456
{ value: 2, done: false }
789
{ value: 3, done: false }
应用场景:自增ID。
function *IdMaker(){
let id = 0
while(true){
yield id ++
}
}
const id = IdMaker()
console.log(id.next().value);
console.log(id.next().value);
console.log(id.next().value);
console.log(id.next().value);
//输出结果
0
1
2
3