一、迭代器
什么是迭代
迭代就是从一个数据集合中按照一定的顺序,不断的取出数据的过程。
迭代器(Iterator)
对迭代过程的封装,带有特殊接口的对象。
具有 next() 方法的对象,每次调用 next() 都会返回一个结果对象,结果对象有两个属性,value 表示当前的值,done 表示遍历是否结束
ES5中创建迭代器
function createIterator(arr) {
let i = 0;
return {
next() {
let res = {
value : arr[i],
done : i >= arr.length,
}
i++;
return res;
}
}
}
const iterator = createIterator([3, 6, 9]);
console.log(iterator.next()); //{value: 3, done: false}
console.log(iterator.next()); //{value: 6, done: false}
console.log(iterator.next()); //{value: 9, done: false}
console.log(iterator.next()); //{value: undefined, done: true}
for of
在ES6中用for of
语句,专门遍历可迭代的对象的,不是可迭代的对象不能使用for of
遍历,遍历迭代器对象。
可以使用break, throw 或return 等终止,可迭代数组。
可迭代的数据结构有Array、String、Map、Set和DOM元素。
//for of 不可遍历不是迭代的对象
const obj = {x : 1, y : 3}
for (let value of obj ) {
console.log(value); // Uncaught TypeError: obj is not iterable
}
在这就可以通过对象的Symbol.iterator
属性,指向该对象的默认遍历器方法,找不到该属性不能遍历,找到了该属性就可以遍历。
Symbol.iterator 属性
在es6中,如果对象具有知名符号的属性 Symbol.iterator,表示对象可以迭代。
const arr = [12, 18, 49, 10, 9];
const iterator = arr[Symbol.iterator]();
console.log(iterator.next()) //{value: 12, done: false}
console.log(iterator.next()) //{value: 18, done: false}
console.log(iterator.next()) //{value: 49 done: false}
console.log(iterator.next()) //{value: 10, done: false}
console.log(iterator.next()) //{value: 9, done: false}
console.log(iterator.next()) //{value: undefined, done: true}
当用扩展运算符(…)或者对数组和 Set 结构进行解构赋值时,会默认调用Symbol.iterator方法。
let arr1 = [1, 3, 5]
let arr2 = [2, 3, 4, 5]
arr2 = [1,...arr2,6]
console.log(arr2) // [1, 2, 3, 4, 5, 6]
二、生成器
概念
生成器就是通过构造函数Generator创建出来的对象,生成器既是一个迭代器也是一个可迭代的对象,yield可暂停,next方法可启动。每次返回的是yield后的表达式结果。
语法:function* fun() {}
function *generator() {
yield 1;
yield 2;
yield 3;
}
const gen = generator();
console.log(gen.next()); // {value:1, done: false}
console.log(gen.next()); // {value:2, done: false}
console.log(gen.next()); // {value:3, done: false}
console.log(gen.next()); // {value: undefined, done: true}
let obj = { uname: 'yaya', age: 21 }
obj[Symbol.iterator] = function *fun() {
yield 3;
yield 6;
yield 9;
};
for (let val of obj) {
console.log(val) // 1 2 3
}
上面例子中,Generator函数赋值给Symbol.iterator
属性,让obj对象具有了 Iterator 接口,就可以用for of
遍历,不需要调用next()
方法