它的定义:
迭代器是一个对象,它定义一个序列,并在终止时可能返回一个返回值。任何数据部署了iterato接口,就可以完成遍历操作。
- es6创建了一个新的遍历方for…of,主要就是提供接口消费的。
- 原生具备for…of遍历的有(也就是说有interato接口)
1.array
2.arguments
3.set
4.map
5.string
- 工作原理
1.创建一个指针对象,指向当前的数据结构的起始位置
2.第一次调用对象的next方法,指向数据结构的第一个成员。
3.不断的调用next方法,指针不断向后移动,直到指向最后一个成员。
4.每一次调用,都返回一个value和done属性的对象
使用for…of
const arr = ['张三', '李四', '王五']
// 使用for...of
for (let v of arr) {
console.log(v);
}
console.log(arr);
打印数据的原型中可以看到数组带有一个私有的方法
// 查看这个,注意后面的要用中括号,因为数据是Symbol定义一种方法,还需要用()
let iterator = arr[Symbol.iterator]()
console.log(iterator);
在这里我们就可以看到上面提的工作原理的第二点;
当我们使用next方法就可以指向数组第一项。
console.log(iterator.next());
console.log(iterator.next());
console.log(iterator.next());
console.log(iterator.next());
console.log(iterator.next());
当指向没有时,给我们返回一个undefined和true,也就是结束了它自身的循环.
知道了这些就可以实现自定义遍历数据了。
自定义遍历数据
为什么我们要自定义遍历数据?
比喻:我有一个小金库,你来找我借钱,需要经过我的同意吧!也就是使用(for…of),而不是通过暴力的方法,也就是通过(forEach),直接暴力的使用。
这样做也就不符合我面向对象编程。
// 要求遍历stus
// 我们当然可以使用forEach来遍历,但不符合我们要求
// 这个时候我们就要给他创建一个接口
const obj = {
name: '西游记',
stus: [
'swk', 'zbj', 'shs', 'ts'
],
[Symbol.iterator]() {
// 定义一个下标
let index = 0
let _this = this
// 返回我们工作原理的第一句,也就next()方法
// 注意一定要有自定义的下标,用来做它关闭的条件,不然就会出现无限循环
return {
next: function () {
if (index < _this.stus.length) {
// 在它的原理中,需要返回一个value和done
const result = { value: _this.stus[index], done: false }
// 下标自增,关闭条件
index++;
// 返回结果
return result
} else {
return { value: undefined, done: true }
}
}
}
}
}
for (let v of obj) {
console.log(v)
}
写了那么多,它到底有什么用,我也不太明白。
阮一峰的讲解:
https://www.yuque.com/ostwind/es6/docs-iterator