Iterator是一种接口机制,为各种不同的数据结构提供统一访问的机制,主要供for…of消费,让不支持遍历的数据结构“可遍历”
1、类似generator yield
function makeIterator(arr) {
let nextIndex = 0;
return {
next() {
return nextIndex < arr.length ? {
value:arr[nextIndex++],
done:false
} : {
value:undefined,
done:true
}
}
}
}
let it = makeIterator(['a', 'b', 'c']);
// 相当于一个指针,指向数据结构的成员
console.log(it.next());//{value: "a", done: false}
console.log(it.next());//{value: "b", done: false}
console.log(it.next());//{value: "c", done: false}
console.log(it.next());//{value: undefined, done: true}
2、不可遍历
courses对象没有自带的iterator,在4中实现
let courses = {
allCourse:{
frontend:['ES','小程序', 'Vue', 'React'],
backend:['Java', 'Python', 'Spring Boot'],
webapp:['Android', 'IOS']
}
}
// for (let c of courses) {
// console.log(c);
// }
3、原生的对象 自带Symbol.iterator
Array、Map、Set、String、TypedArray、arguments对象、NodeList对象
//Array
let arr = ['a', 'b', 'c'];
console.log(arr);
let obj1 = arr[Symbol.iterator]();
console.log(obj1.next());//{value: "a", done: false}
console.log(obj1.next());//{value: "b", done: false}
console.log(obj1.next());//{value: "c", done: false}
console.log(obj1.next());//{value: undefined, done: true}
//Map
let map = new Map();
map.set('name', 'es');
map.set('age', 5);
let obj2 = map[Symbol.iterator]();
console.log(obj2.next());//{value: Array(2), done: false}
console.log(obj2.next());//{value: Array(2), done: false}
console.log(obj2.next());//{value: undefined, done: true}
4、对实现一个迭代器
规则: 可迭代协议:Symbol.iterator 迭代器协议:return {next(){ return {value, done}}}
courses[Symbol.iterator] = function() {
let allCourse = this.allCourse;
// 获取keys 静态方法 Reflect.ownKeys() 返回一个由目标对象自身的属性键组成的数组。
let keys = Reflect.ownKeys(allCourse);
let values = [];
return {
next() {
if(!values.length) {
if(keys.length) {
//frontend
//backend
//webapp
values = allCourse[keys[0]];
keys.shift();
}
}
return {
done: !values.length,
value:values.shift(),
}
}
}
}
for (let allc of courses) {
console.log(allc);
}
输出
5、 generator
静态方法 Reflect.ownKeys() 返回一个由目标对象自身的属性键组成的数组。
courses[Symbol.iterator] = function* () {
let allCourse = this.allCourse;
let keys = Reflect.ownKeys(allCourse);
let values = [];
while (1) {
if(!values.length) {
if(keys.length) {
values = allCourse[keys[0]];
keys.shift();
yield values.shift();
} else {
return false;
}
} else {
yield values.shift();
}
}
}
for (let allc of courses) {
console.log(allc);
}
输出