1.迭代器
迭代就是将一种数据结构按照一定的顺序不断的取出的过程就叫迭代。js中规定一个对象中含有next方法,并且这个next方法返回一个对象 ,那么我们就认为这个对象为迭代器。
迭代和遍历是有区别的,遍历是运用循环将数据一次性取完,而迭代是将数据依次取出,一次只能去到一个数据。
自定义迭代器
var obj = {
next() {// 用于拿到后面的数据
return {
value : "Hello World", // 就是返回的数据
done : false //判断是否还有下一个数据
}
}
}
// 让迭代器自己取数据
let res = iterator.next();
while(!res.done) {
console.log(res.value);
// 需要给迭代器设置结束条件 重新给res赋值 得到新的迭代状态
res = iterator.next();
}
console.log("迭代完成");
既然我们能够完成自定义迭代器,那我们也可以设置数组的迭代器和对象的迭代器。在ES6里面如果对象具有Symbol.iterator这个属性 ,那么就说明这个对象是可以进行迭代的。
var arr = [10, 20, 30, 40];
console.log(arr[Symbol.iterator]);
let iter = arr[Symbol.iterator]()
let res = iter.next();
while(!res.done) {
console.log(res.value);
res = iter.next();
}
对象的迭代器
Symbol.iterator属性 对应的是一个方法 返回一个对象 里面包含next方法 next方法返回值里面包含了两个键 value(表示迭代到的值) done(是否继续往后迭代)
var obj = {
a : 1,
b : 2,
c : 3,
[Symbol.iterator] () {
// 拿到对象所有的键名
const keys = Object.keys(this);
let i = 0
// 设置迭代器
return {
next : () => {
const propName = keys[i];
const propValue = this[propName];
var result = {
value : {
propName,
propValue
},
done : i++ >= keys.length
}
return result;
}
}
}
}
for(const key of obj) {
console.log(key);
}
2.生成器
generator(生成器)是ES6标准引入的新的数据类型。一个generator看上去像一个函数,但可以返回多次。
与函数的不同之处:
generator和函数不同的是,generator由function定义(注意多出的号),并且,除了return语句,还可以用yield返回多次。
function* fn() {
console.log("1");
yield "2";
yield "3";
yield "4";
console.log("5");
return "end"
}
var fn = fn();
console.log(fn);
console.log(fn.next());
console.log(fn.next());
console.log(fn.next());
console.log(fn.next());
console.log(fn.next());
调用next方法:
1.当函数调用next方法之后,在函数内部遇到了yield关键字函数就会暂停执行,next方法的返回值就是yeild后面接的数据
2.当我们再次调用next方法时,就会从当前暂停的位置继续往下走直到遇到下一个yield
3.运行到最后没有yield关键字,就会一直往后执行直到遇到return关键字,返回的是return后面的值并且状态变成true
4.最后如果没有遇到return返回值为undefined,状态就为true
generator(生成器)函数的特点:
1.generator函数是分步执行的,以yield 为标志,遇到之后就暂停执行,通过调用next方法恢复函数执行.
2.generator函数的写法跟普通函数有区别就是在function关键字和函数名之前加一个* 要紧挨着function写
3.generator函数如果直接调用是不会执行的,只能通过调用next方法往下执行。
4.generator函数调用之后 ,返回的值是一个iterator对象 ,只有调用next方法,才会迭代 进入下一个状态
需要注意的是:生成器也是一种迭代器,所以可以进行迭代,但是Async和 * 不能同时使用