JS规定,如果一个对象具有next方法,并且该方法返回一个对象,该对象的格式如下:
{value:值,done:是否迭代完成}
则认为该对象是一个迭代器
next方法:用于得到下一个数据
返回的对象
- value:下一个数据的值
- done:boolean,是否迭代完成
1.迭代器数组
const arr = [1, 2, 3, 4, 5]
// 迭代数组arr
const iterator = {
i: 0, //当前数组下标
next() {
var result = {
value: arr[this.i],
done: this.i >= arr.length,
}
this.i++
return result
},
}
// 让迭代器不断的取出下一个数据,知道没有数据为止
let data = iterator.next()
while (!data.done) {
console.log(iterator.next())
data = iterator.next()
}
console.log('迭代完成')
2.迭代器创建函数
const arr1 = [1, 2, 3, 4, 5]
const arr2 = [3, 2, 5, 3, 21, 4]
// 迭代器创建函数
function createIterator (arr) {
let i = 0
return {
next () {
var result = {
value: arr[i],
done: i >= arr.length,
}
i++
return result
},
}
}
const iter1 = createIterator(arr1)
const iter2 = createIterator(arr2)
3.斐波那契数列迭代器
// 创建一个斐波那契数列的迭代器
function createFeiboIterator() {
let prev1 = 1,
prev2 = 1 //当前位置的前一位和前二位
n = 1 // 当前是第几位
return {
next() {
let value
if (n <= 2) {
value = 1
} else {
value = prev1 + prev2
}
const result = {
value,
done: false,
}
prev2 = prev1
prev1 = result.value
n++
return result
},
}
}
const iter = createFeiboIterator()
4.迭代器协议
Es6规定,如果一个对象具有知名符号属性Symbol.iterator,并且属性值是一个迭代器创建函数
则该对象是可迭代的
// 可迭代对象
var obj = {
[Symbol.iterator] () {
return {
next () {
return {
value: 1, done, false
}
},
}
},
}
5.数组中的迭代器
const arr = [1, 2, 3, 4, 5]
const iter = arr[Symbol.iterator]()
取出数组中的数据
let result = iter.next()
while (!result.done) {
const item = result.value
console.log(item)
// 下一次迭代
result = iter.next()
}
6.for of语法糖
数组
const arr = [1, 2, 3, 4, 5]
const iter = arr[Symbol.iterator]()
for (const item of arr) {
console.log(item)
}
对象
const obj = {
a: 0,
b: 1,
[Symbol.iterator] () {
const keys = Object.keys(this)
let i = 0
return {
next: () => {
const propName = keys[i]
const propValue = this[propName]
const result = {
value: {
propName,
propValue,
},
done: i >= keys.length,
}
i++
return result
},
}
},
}
for (const item of obj) {
console.log(item)
}
const arr = [...obj]
console.log(arr)
展开运算符可以作用于可迭代对象
这样,可以轻松的将可迭代对象转换位数组
7.伪数组中的迭代器
<div>1</div>
<div>2</div>
···
<div>10</div>
const divs = document.querySelectorAll('div')
const iter = divs[Symbol.iterator]()