9.2 自定义迭代器与 Symbol.iterator

9.2 自定义迭代器与 Symbol.iterator

在 JavaScript 中,自定义迭代器允许我们为对象定义自己的遍历行为。通过实现 Symbol.iterator 方法,我们可以使对象成为可迭代对象,从而支持 for...of 循环等迭代操作。本节将详细介绍如何自定义迭代器及其应用场景。


9.2.1 自定义迭代器的基本概念

自定义迭代器需要实现 Symbol.iterator 方法,该方法返回一个迭代器对象。迭代器对象必须实现 next() 方法,用于产生一系列的值。

1. Symbol.iterator 方法
Symbol.iterator 是一个内置的 Symbol 值,表示对象的默认迭代器方法。

2. next() 方法
next() 方法返回一个包含 valuedone 属性的对象:

  • value:当前迭代的值。
  • done:布尔值,表示迭代是否完成。

9.2.2 自定义迭代器的实现

1. 基本实现

const customIterable = {
  [Symbol.iterator]() {
    let step = 0;
    return {
      next() {
        step++;
        if (step === 1) {
          return { value: "First", done: false };
        } else if (step === 2) {
          return { value: "Second", done: false };
        } else {
          return { value: undefined, done: true };
        }
      },
    };
  },
};

for (const value of customIterable) {
  console.log(value); // 输出 "First" 和 "Second"
}

2. 使用类的实现
通过类实现自定义迭代器,可以更好地组织代码:

class CustomIterable {
  constructor() {
    this.steps = ["First", "Second"];
  }

  [Symbol.iterator]() {
    let index = 0;
    return {
      next: () => {
        if (index < this.steps.length) {
          return { value: this.steps[index++], done: false };
        } else {
          return { value: undefined, done: true };
        }
      },
    };
  }
}

const iterable = new CustomIterable();
for (const value of iterable) {
  console.log(value); // 输出 "First" 和 "Second"
}

9.2.3 自定义迭代器的应用场景

1. 自定义数据结构
为自定义数据结构(如链表、树等)实现迭代器,使其支持 for...of 循环。

2. 惰性求值
通过迭代器实现惰性求值,只在需要时计算值,节省内存和计算资源。

3. 生成无限序列
通过迭代器生成无限序列(如斐波那契数列),只在需要时产生值。


9.2.4 示例代码

示例 1:自定义链表迭代器

class Node {
  constructor(value, next = null) {
    this.value = value;
    this.next = next;
  }
}

class LinkedList {
  constructor() {
    this.head = null;
  }

  add(value) {
    this.head = new Node(value, this.head);
  }

  [Symbol.iterator]() {
    let current = this.head;
    return {
      next() {
        if (current) {
          const value = current.value;
          current = current.next;
          return { value, done: false };
        } else {
          return { value: undefined, done: true };
        }
      },
    };
  }
}

const list = new LinkedList();
list.add(3);
list.add(2);
list.add(1);

for (const value of list) {
  console.log(value); // 输出 1, 2, 3
}

示例 2:生成斐波那契数列

class Fibonacci {
  constructor(limit = Infinity) {
    this.limit = limit;
  }

  [Symbol.iterator]() {
    let prev = 0,
      curr = 1,
      count = 0;
    return {
      next: () => {
        if (count++ < this.limit) {
          const value = curr;
          [prev, curr] = [curr, prev + curr];
          return { value, done: false };
        } else {
          return { value: undefined, done: true };
        }
      },
    };
  }
}

const fibonacci = new Fibonacci(5);
for (const value of fibonacci) {
  console.log(value); // 输出 1, 1, 2, 3, 5
}

9.2.5 总结

  • 自定义迭代器:通过实现 Symbol.iterator 方法,定义对象的遍历行为。
  • next() 方法:用于产生一系列的值,返回 valuedone 属性。
  • 应用场景:自定义数据结构、惰性求值、生成无限序列。

通过掌握自定义迭代器的实现,你可以为对象定义灵活的遍历行为,满足各种复杂的需求。在接下来的学习中,我们将继续探索 JavaScript 的其他高级特性。


思考题

  1. 如何为自定义数据结构实现迭代器?
  2. 自定义迭代器的主要应用场景有哪些?
  3. 如何通过迭代器实现惰性求值?
#前端开发 分享于 2025-03-21

【 内容由 AI 共享,不代表本站观点,请谨慎参考 】