JavaScript中的迭代协议与可迭代对象
字数 486 2025-11-12 17:24:05

JavaScript中的迭代协议与可迭代对象

迭代协议是ES6引入的一组规则,它定义了如何遍历数据结构。协议分为两种:可迭代协议和迭代器协议。

可迭代协议

  • 一个对象要实现可迭代协议,必须包含一个特殊属性:Symbol.iterator
  • 这个属性值必须是一个无参函数,调用后返回一个迭代器对象

迭代器协议

  • 迭代器是实现了next()方法的对象
  • next()方法必须返回一个包含两个属性的对象:
    • value: 当前迭代的值
    • done: 布尔值,表示迭代是否完成

实现过程详解

  1. 基本迭代器实现
// 创建一个简单的迭代器
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}
  1. 实现可迭代对象
// 创建一个可迭代对象
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'
}
  1. 使用生成器函数简化实现
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
}
  1. 自定义范围迭代器
// 创建一个数字范围的可迭代对象
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集合

使用场景

  1. for...of循环
const arr = [1, 2, 3]
for (const item of arr) {
  console.log(item)
}
  1. 展开运算符
const set = new Set([1, 2, 3])
console.log([...set]) // [1, 2, 3]
  1. 解构赋值
const [first, second] = 'hello'
console.log(first, second) // 'h', 'e'
  1. Array.from()
const map = new Map([['a', 1], ['b', 2]])
console.log(Array.from(map)) // [['a', 1], ['b', 2]]

注意事项

  • 迭代器是单向的,只能遍历一次
  • 可以手动调用迭代器进行更精细的控制
  • 生成器函数返回的就是一个可迭代对象

理解迭代协议有助于创建自定义的数据结构,并能与JavaScript的迭代机制无缝集成。

JavaScript中的迭代协议与可迭代对象 迭代协议是ES6引入的一组规则,它定义了如何遍历数据结构。协议分为两种:可迭代协议和迭代器协议。 可迭代协议 一个对象要实现可迭代协议,必须包含一个特殊属性: Symbol.iterator 这个属性值必须是一个无参函数,调用后返回一个迭代器对象 迭代器协议 迭代器是实现了 next() 方法的对象 next() 方法必须返回一个包含两个属性的对象: value : 当前迭代的值 done : 布尔值,表示迭代是否完成 实现过程详解 基本迭代器实现 实现可迭代对象 使用生成器函数简化实现 自定义范围迭代器 内置可迭代对象 Array、String、Map、Set、TypedArray、arguments对象 NodeList等DOM集合 使用场景 for...of循环 展开运算符 解构赋值 Array.from() 注意事项 迭代器是单向的,只能遍历一次 可以手动调用迭代器进行更精细的控制 生成器函数返回的就是一个可迭代对象 理解迭代协议有助于创建自定义的数据结构,并能与JavaScript的迭代机制无缝集成。