JavaScript中的迭代器协议与for...of循环
字数 655 2025-11-21 14:49:46

JavaScript中的迭代器协议与for...of循环

描述
迭代器协议是ES6引入的一组规则,定义了如何顺序访问数据集合中的元素。任何对象只要实现了next()方法,就被认为是一个迭代器。for...of循环则是基于迭代器协议的语法糖,能够自动遍历可迭代对象。

核心概念解析

  1. 可迭代对象(Iterable)

    • 必须实现[Symbol.iterator]()方法,该方法返回一个迭代器对象
    • 常见可迭代对象:Array、String、Map、Set、NodeList等
  2. 迭代器对象(Iterator)

    • 必须实现next()方法,返回{value: any, done: boolean}形式的对象
    • done: true时表示遍历结束

实现步骤详解

  1. 基础迭代器实现

    function createCounter(max) {
      let count = 1
      return {
        next() {
          if (count <= max) {
            return { value: count++, done: false }
          }
          return { value: undefined, done: true }
        }
      }
    }
    
    const counter = createCounter(3)
    console.log(counter.next()) // {value: 1, done: false}
    console.log(counter.next()) // {value: 2, done: false}
    console.log(counter.next()) // {value: 3, done: false}
    console.log(counter.next()) // {value: undefined, done: true}
    
  2. 使对象可迭代

    const myIterable = {
      data: [10, 20, 30],
      [Symbol.iterator]() {
        let index = 0
        return {
          next: () => {
            if (index < this.data.length) {
              return { value: this.data[index++], done: false }
            }
            return { done: true }
          }
        }
      }
    }
    
    // 现在可以用for...of遍历
    for (const item of myIterable) {
      console.log(item) // 依次输出10, 20, 30
    }
    
  3. 生成器简化实现

    const simpleIterable = {
      *[Symbol.iterator]() {
        yield 1
        yield 2
        yield 3
      }
    }
    

for...of运行机制

  1. 首先调用对象的[Symbol.iterator]()方法获取迭代器
  2. 循环调用迭代器的next()方法
  3. 将返回对象的value属性赋值给循环变量
  4. done: true时退出循环

与传统遍历对比

  • for循环:需要维护索引,适合数组
  • for...in:遍历键名,包括原型链属性
  • for...of:直接遍历值,更简洁安全

实际应用场景

  1. 自定义数据结构遍历:

    class Range {
      constructor(start, end) {
        this.start = start
        this.end = end
      }
    
      *[Symbol.iterator]() {
        for (let i = this.start; i <= this.end; i++) {
          yield i
        }
      }
    }
    
    for (const num of new Range(1, 5)) {
      console.log(num) // 1,2,3,4,5
    }
    
  2. 与解构赋值结合:

    const [first, second] = myIterable // first=10, second=20
    

注意事项

  1. 迭代器是单向的,遍历后不能重置
  2. 可迭代对象可以创建多个独立的迭代器
  3. 手动调用next()时,最后返回done: true后应继续返回相同结果
JavaScript中的迭代器协议与for...of循环 描述 迭代器协议是ES6引入的一组规则,定义了如何顺序访问数据集合中的元素。任何对象只要实现了next()方法,就被认为是一个迭代器。for...of循环则是基于迭代器协议的语法糖,能够自动遍历可迭代对象。 核心概念解析 可迭代对象(Iterable) : 必须实现 [Symbol.iterator]() 方法,该方法返回一个迭代器对象 常见可迭代对象:Array、String、Map、Set、NodeList等 迭代器对象(Iterator) : 必须实现 next() 方法,返回 {value: any, done: boolean} 形式的对象 当 done: true 时表示遍历结束 实现步骤详解 基础迭代器实现 : 使对象可迭代 : 生成器简化实现 : for...of运行机制 首先调用对象的 [Symbol.iterator]() 方法获取迭代器 循环调用迭代器的 next() 方法 将返回对象的 value 属性赋值给循环变量 当 done: true 时退出循环 与传统遍历对比 for循环 :需要维护索引,适合数组 for...in :遍历键名,包括原型链属性 for...of :直接遍历值,更简洁安全 实际应用场景 自定义数据结构遍历: 与解构赋值结合: 注意事项 迭代器是单向的,遍历后不能重置 可迭代对象可以创建多个独立的迭代器 手动调用 next() 时,最后返回 done: true 后应继续返回相同结果