JavaScript中的迭代协议与可迭代对象
字数 486 2025-11-12 17:24:05
JavaScript中的迭代协议与可迭代对象
迭代协议是ES6引入的一组规则,它定义了如何遍历数据结构。协议分为两种:可迭代协议和迭代器协议。
可迭代协议
- 一个对象要实现可迭代协议,必须包含一个特殊属性:
Symbol.iterator - 这个属性值必须是一个无参函数,调用后返回一个迭代器对象
迭代器协议
- 迭代器是实现了
next()方法的对象 next()方法必须返回一个包含两个属性的对象:value: 当前迭代的值done: 布尔值,表示迭代是否完成
实现过程详解
- 基本迭代器实现
// 创建一个简单的迭代器
const simpleIterator = {
data: [1, 2, 3],
index: 0,
next() {
if (this.index < this.data.length) {
return { value: this.data[this.index++], done: false }
} else {
return { value: undefined, done: true }
}
}
}
console.log(simpleIterator.next()) // {value: 1, done: false}
console.log(simpleIterator.next()) // {value: 2, done: false}
console.log(simpleIterator.next()) // {value: 3, done: false}
console.log(simpleIterator.next()) // {value: undefined, done: true}
- 实现可迭代对象
// 创建一个可迭代对象
const myIterable = {
data: ['a', 'b', 'c'],
// 实现Symbol.iterator方法
[Symbol.iterator]() {
let index = 0
const data = this.data
// 返回迭代器对象
return {
next() {
if (index < data.length) {
return { value: data[index++], done: false }
} else {
return { value: undefined, done: true }
}
}
}
}
}
// 测试可迭代对象
for (const item of myIterable) {
console.log(item) // 依次输出: 'a', 'b', 'c'
}
- 使用生成器函数简化实现
const myIterableWithGenerator = {
data: [10, 20, 30],
// 使用生成器函数更简洁
*[Symbol.iterator]() {
for (const item of this.data) {
yield item
}
}
}
// 效果相同
for (const num of myIterableWithGenerator) {
console.log(num) // 10, 20, 30
}
- 自定义范围迭代器
// 创建一个数字范围的可迭代对象
class NumberRange {
constructor(start, end, step = 1) {
this.start = start
this.end = end
this.step = step
}
*[Symbol.iterator]() {
let current = this.start
while (this.step > 0 ? current <= this.end : current >= this.end) {
yield current
current += this.step
}
}
}
// 使用示例
const range = new NumberRange(1, 5)
console.log([...range]) // [1, 2, 3, 4, 5]
const reverseRange = new NumberRange(5, 1, -1)
console.log([...reverseRange]) // [5, 4, 3, 2, 1]
内置可迭代对象
- Array、String、Map、Set、TypedArray、arguments对象
- NodeList等DOM集合
使用场景
- for...of循环
const arr = [1, 2, 3]
for (const item of arr) {
console.log(item)
}
- 展开运算符
const set = new Set([1, 2, 3])
console.log([...set]) // [1, 2, 3]
- 解构赋值
const [first, second] = 'hello'
console.log(first, second) // 'h', 'e'
- Array.from()
const map = new Map([['a', 1], ['b', 2]])
console.log(Array.from(map)) // [['a', 1], ['b', 2]]
注意事项
- 迭代器是单向的,只能遍历一次
- 可以手动调用迭代器进行更精细的控制
- 生成器函数返回的就是一个可迭代对象
理解迭代协议有助于创建自定义的数据结构,并能与JavaScript的迭代机制无缝集成。