迭代器(Iterator)概述
- 迭代器是一种特殊对象,每一个迭代器对象都有一个
next()
,该方法返回一个对象,包括value
和done
属性。 - 在ES6中,Array、Map、Set、字符串都属于可迭代对象。
ES5实现迭代器
// 实现一个返回迭代器对象的函数、注意该函数不是迭代器、返回结果才叫做迭代器。
function createIterator(items){
let i = 0;
return {
next() {
let done = (i >= items.length); // 判断i是否小于遍历的对象长度
let value = !done ? items[i++] : undefined // 如果done为false、设置value为当前遍历的值。
return {
done,
value
}
}
}
}
const a = createIterator([1,2,3]);
console.log(a.next());
console.log(a.next());
console.log(a.next());
console.log(a.next());
运行结果:
生成器(Generator)概述
- 生成器是一个特殊的函数,用来返回迭代器。
- 这个概念有两个关键点,一个是函数,一个是返回迭代器。这个函数不是上面ES5中创建迭代器的函数,而是ES6中特有的,一个带有*(星号)的函数,同时函数体内用了一个新的关键字yield,来表示每次迭代的节点。
- 调用生成器函数时会生成一个生成器对象,当调用
next()
时就去执行里面的内容。直到碰到yield这个关键字的时候停止,并把yield的值返回出去。下一次调用时就会在之前的yield节点继续往下执行。 - 使用生成器必须声明变量去获取它,不然每次执行
next()
返回的都是第一个节点。
创建生成器实例
function *g(){
yield 1;
yield 2;
yield 3;
}
let runG = g();
console.log(runG.next());
console.log(runG.next());
console.log(runG.next());
console.log(runG.next());
运行结果:
- 生成器一般用于自定义的迭代逻辑,为
for of
服务。 - 当开发大型应用或框架时,可以使用生成器去代替数组对象,这样可以减少内存消耗。
创建可迭代对象
- 默认情况下定义的对象(object)是不可迭代的,但是可以通过
Symbol.iterator
创建迭代器。
const obj = {
items:[1,2,3],
// 给obj添加Symbol.iterator,使obj成为可迭代对象。
*[Symbol.iterator](){
for(let item of this.items){
yield item;
}
}
}
for(let x of obj){
console.log(x);
}
运行结果:
内建迭代器
- Array、Set、Map内部实现了迭代器,并且提供了3种迭代器函数调用。
entries()
返回迭代器:
const arrayObj = ['a','b','c'];
const setObj = new Set(['a','b','c']);
const mapObj = new Map();
mapObj.set('a','a');
mapObj.set('b','b');
mapObj.set('c','c');
console.log('arrayObj');
for(let value of arrayObj.entries()){
console.log(value);
}
console.log('setObj');
for(let value of setObj.entries()){
console.log(value);
}
console.log('mapObj');
for(let value of mapObj.entries()){
console.log(value);
}
运行结果:
values()
返回迭代器:
const arrayObj = ['a','b','c'];
const setObj = new Set(['a','b','c']);
const mapObj = new Map();
mapObj.set('a','a');
mapObj.set('b','b');
mapObj.set('c','c');
console.log('arrayObj');
for(let value of arrayObj.values()){
console.log(value);
}
console.log('setObj');
for(let value of setObj.values()){
console.log(value);
}
console.log('mapObj');
for(let value of mapObj.values()){
console.log(value);
}
运行结果:
keys()
返回迭代器:
const arrayObj = ['a','b','c'];
const setObj = new Set(['a','b','c']);
const mapObj = new Map();
mapObj.set('a','a');
mapObj.set('b','b');
mapObj.set('c','c');
console.log('arrayObj');
for(let value of arrayObj.keys()){
console.log(value);
}
console.log('setObj');
for(let value of setObj.keys()){
console.log(value);
}
console.log('mapObj');
for(let value of mapObj.keys()){
console.log(value);
}
运行结果:
entries()
:返回键值对。keys()
:返回键值对的key。values()
:返回键值对的value。