要让对象支持for...of等遍历,需实现[Symbol.iterator]()方法并返回符合迭代器协议的对象;该方法须返回含next()的对象,next()每次返回{value, done}。

要让一个对象能被 for...of、展开运算符([...obj])或 Array.from() 正常遍历,关键不是写个循环,而是让它“说自己可迭代”——也就是实现 [Symbol.iterator]() 方法,并返回一个符合迭代器协议的对象。
必须满足的两个协议层级
可迭代对象 ≠ 迭代器本身,它们是两层关系:
-
可迭代协议:对象上要有
[Symbol.iterator]属性,它是一个无参函数,调用后必须返回一个迭代器对象; -
迭代器协议:返回的那个对象必须有
next()方法,每次调用都返回{ value, done }形式的对象。
手写一个带状态的可迭代对象(比如数字范围)
下面这个 Range 对象从 from 到 to(含),每次迭代返回一个整数:
function*
-
next()返回的value在done: true时可以省略,但不要返回{ value: undefined, done: true }—— 这虽合法,但可能干扰某些工具链对“结束值”的判断; -
[Symbol.iterator]必须是函数,不能是箭头函数(否则无法正确绑定this); - 如果想让同一个对象多次遍历(比如反复用
for...of),[Symbol.iterator]每次都应返回**新**的迭代器实例,而不是复用同一个; - 原生类型如数组、字符串已内置该方法;普通对象默认没有,所以
for...of直接遍历普通对象会报错。











