十一、Iterator迭代器
大约 2 分钟约 594 字
(一)Iterator 简介
Iterator
是一种接口【即对象的属性】- 为各种不同的数据结构提供统一的访问机制
- 任何数据结构只要部署
iterator
接口就可以完成遍历操作
ES6
创造了一种新的遍历命令for...of
循环iterator
主要供for...of
消费
- 原生具备
iterator
接口的数据(即可用for...of
遍历)Array
Arguments
Set
Map
String
TypeArray
NodeList
- 需要自定义遍历数据的时候,要想到迭代器
// 声明一个数组
const xiyou = ["唐僧", "孙悟空", "猪八戒", "沙僧"];
// 使用for...in遍历【遍历的是键名】
for (let k in xiyou) {
console.log(k);
}
// 0
// 1
// 2
// 3
// 使用for...of遍历【遍历的是键值】
for (let v of xiyou) {
console.log(v);
}
// 唐僧
// 孙悟空
// 猪八戒
// 沙僧
// 数组可以遍历是因为原型对象上有Symbol(Symbol.iterator): ƒ values()
console.log(xiyou);
(二)工作原理
- 创建一个指针对象,指向当前数据结构的起始位置
- 第一次调用对象的
next
方法,指针自动指向数据结构的第一个成员 - 接下来不断调用
next
方法,指针一直往后移动,直到指向最后一个成员 - 每调用一次
next
方法返回一个包含value
和done
属性的对象
let iterator = xiyou[Symbol.iterator]();
console.log(iterator);
// Array Iterator {} 原型里有next()
// 调用对象的next方法
console.log(iterator.next());
// {value: '唐僧', done: false}
console.log(iterator.next());
// {value: '孙悟空', done: false}
console.log(iterator.next());
// {value: '猪八戒', done: false}
console.log(iterator.next());
// {value: '沙僧', done: false}
console.log(iterator.next());
// {value: undefined, done: true}
(三)自定义遍历数据
- 需求:使用
for...of
遍历这个对象,返回结果是stus
数组的一个成员
1.banji.stus.forEach()
- 可以实现,但是不符合面向对象的思想,
- 最好不要直接操作对象中的属性
- 应该通过对象暴露出来的方法获得相应的属性
// 声明一个对象
const banji = {
name: "终极一班",
stus: ["xiaoming", "xiaoning", "xiaotian", "knight"],
};
for (let v of banji) {
console.log(v);
}
// banji is not iterable
2.Symbol.iterator
// 声明一个对象
const banji = {
name: "终极一班",
stus: ["xiaoming", "xiaoning", "xiaotian", "knight"],
[Symbol.iterator]() {
// 索引变量
let index = 0;
return {
next: () => {
if (index < this.stus.length) {
const res = {
value: this.stus[index],
done: false,
};
index++;
return res;
} else {
return {
value: undefined,
done: true,
};
}
},
};
},
};
for (let v of banji) {
console.log(v);
}
// xiaoming
// xiaoning
// xiaotian
// knight