2026-10-22 00:33:12
JavaScript通过实现[Symbol.iterator]方法和生成器函数(function*)来支持迭代协议,使对象可被for...of循环或展开运算符遍历。以下是具体实现方式及核心机制:
一、手动实现可迭代对象定义[Symbol.iterator]方法对象需实现[Symbol.iterator]方法,该方法返回一个包含next()的迭代器对象。next()每次调用返回{ value: 当前值, done: 布尔值 }。
示例:计数器
function createCounter(start, end) { let current = start; return { [Symbol.iterator]() { return { next() { if (current <= end) { return { value: current++, done: false }; } else { return { value: undefined, done: true }; } } }; } };}const myCounter = createCounter(1, 3);for (const num of myCounter) console.log(num); // 输出 1, 2, 3关键点
[Symbol.iterator]是对象可迭代的核心标识。
迭代器通过next()管理状态,done: true终止迭代。
展开运算符(如[...createCounter(5, 7)])同样依赖此协议。
生成器函数(function*)自动管理迭代状态,通过yield产出值,避免手动实现next()。
生成器函数作为[Symbol.iterator]
function createCounterWithGenerator(start, end) { return { [Symbol.iterator]: function* () { for (let i = start; i <= end; i++) yield i; } };}const myGenCounter = createCounterWithGenerator(10, 12);for (const num of myGenCounter) console.log(num); // 输出 10, 11, 12直接使用生成器函数生成器函数本身返回迭代器,可直接遍历:
function* simpleGenerator() { yield 'Hello'; yield 'World'; yield '!';}for (const item of simpleGenerator()) console.log(item); // 输出 Hello, World, !优势
代码简洁:无需手动维护value和done。
状态自动管理:yield暂停执行,下次调用从暂停处继续。
适用复杂逻辑:如异步迭代、无限序列等。
工作原理
调用对象的[Symbol.iterator]获取迭代器。
反复调用next(),检查done属性:
done: false:将value赋给变量,执行循环体。
done: true:终止循环。
与for...in的区别
for...in遍历对象属性名(包括原型链),而for...of遍历可迭代对象的值。
for...of仅适用于数组、字符串、Map、Set等实现迭代协议的对象。