JavaScript中的迭代器协议与可迭代对象
字数 874 2025-11-15 07:12:20

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

描述
迭代器协议(Iterator Protocol)是ES6引入的一种标准机制,用于定义如何遍历数据集合中的元素。任何对象只要实现了特定的next()方法,就被认为是一个迭代器。而可迭代对象(Iterable)则实现了@@iterator方法(通过Symbol.iterator键访问),该方法返回一个迭代器。常见的可迭代对象包括数组、字符串、Map、Set等。


1. 迭代器的基本结构
一个迭代器必须实现next()方法,该方法返回一个包含两个属性的对象:

  • value:当前迭代的值(若迭代完毕则为undefined)。
  • done:布尔值,表示迭代是否完成。

示例:

const simpleIterator = {
  next() {
    return { value: 1, done: false }; // 永远返回1,永不结束(实际需控制结束条件)
  }
};

2. 实现一个自定义迭代器
假设要遍历一个数字范围(如1到3),需通过闭包保存当前状态:

function createRangeIterator(start, end) {
  let current = start;
  return {
    next() {
      if (current <= end) {
        return { value: current++, done: false };
      }
      return { value: undefined, done: true };
    }
  };
}

const iterator = createRangeIterator(1, 3);
console.log(iterator.next()); // { value: 1, done: false }
console.log(iterator.next()); // { value: 2, done: false }
console.log(iterator.next()); // { value: 3, done: false }
console.log(iterator.next()); // { value: undefined, done: true }

3. 可迭代对象的定义
若对象具有Symbol.iterator方法,且该方法返回一个迭代器,则该对象是可迭代的。可迭代对象可用于for...of循环、展开运算符(...)等场景。

示例:自定义一个可迭代的“数字范围”对象:

const range = {
  from: 1,
  to: 3,
  [Symbol.iterator]() {
    let current = this.from;
    return {
      next: () => { // 使用箭头函数绑定`this`以访问`from`/`to`
        if (current <= this.to) {
          return { value: current++, done: false };
        }
        return { value: undefined, done: true };
      }
    };
  }
};

// 使用for...of遍历
for (const num of range) {
  console.log(num); // 依次输出1, 2, 3
}

// 使用展开运算符
console.log([...range]); // [1, 2, 3]

4. 内置可迭代对象的迭代器
数组、字符串等内置可迭代对象可直接通过Symbol.iterator获取迭代器:

const arr = [10, 20];
const arrIterator = arr[Symbol.iterator]();
console.log(arrIterator.next()); // { value: 10, done: false }

const str = "hi";
const strIterator = str[Symbol.iterator]();
console.log(strIterator.next()); // { value: 'h', done: false }

5. 迭代协议的应用场景

  • for...of循环:仅适用于可迭代对象。
  • 解构赋值:如const [a, b] = range;
  • Array.from():将可迭代对象转为数组。
  • Map/Set的构造函数new Set(range)

6. 与生成器(Generator)的关系
生成器函数(function*)返回的生成器对象既是迭代器,也是可迭代对象,可简化迭代器实现:

const range = {
  from: 1,
  to: 3,
  *[Symbol.iterator]() { // 生成器方法
    for (let i = this.from; i <= this.to; i++) yield i;
  }
};
console.log([...range]); // [1, 2, 3]

总结
迭代器协议通过标准化遍历行为,使不同数据结构(如自定义对象与内置集合)能统一被遍历。理解迭代器与可迭代对象的区别(迭代器实现next(),可迭代对象实现Symbol.iterator)是关键。实际开发中,生成器常用来快速创建迭代器。

JavaScript中的迭代器协议与可迭代对象 描述 迭代器协议(Iterator Protocol)是ES6引入的一种标准机制,用于定义如何遍历数据集合中的元素。任何对象只要实现了特定的 next() 方法,就被认为是一个迭代器。而可迭代对象(Iterable)则实现了 @@iterator 方法(通过 Symbol.iterator 键访问),该方法返回一个迭代器。常见的可迭代对象包括数组、字符串、Map、Set等。 1. 迭代器的基本结构 一个迭代器必须实现 next() 方法,该方法返回一个包含两个属性的对象: value :当前迭代的值(若迭代完毕则为 undefined )。 done :布尔值,表示迭代是否完成。 示例: 2. 实现一个自定义迭代器 假设要遍历一个数字范围(如1到3),需通过闭包保存当前状态: 3. 可迭代对象的定义 若对象具有 Symbol.iterator 方法,且该方法返回一个迭代器,则该对象是可迭代的。可迭代对象可用于 for...of 循环、展开运算符( ... )等场景。 示例:自定义一个可迭代的“数字范围”对象: 4. 内置可迭代对象的迭代器 数组、字符串等内置可迭代对象可直接通过 Symbol.iterator 获取迭代器: 5. 迭代协议的应用场景 for...of 循环 :仅适用于可迭代对象。 解构赋值 :如 const [a, b] = range; 。 Array.from() :将可迭代对象转为数组。 Map/Set的构造函数 : new Set(range) 。 6. 与生成器(Generator)的关系 生成器函数( function* )返回的生成器对象既是迭代器,也是可迭代对象,可简化迭代器实现: 总结 迭代器协议通过标准化遍历行为,使不同数据结构(如自定义对象与内置集合)能统一被遍历。理解迭代器与可迭代对象的区别(迭代器实现 next() ,可迭代对象实现 Symbol.iterator )是关键。实际开发中,生成器常用来快速创建迭代器。