ES6通过提供一个新的协议,即迭代器协议来实现迭代器。迭代器协议定义了一种统一的方式,使得任何对象只要遵循这个协议,都可以被迭代。迭代器协议要求实现两个方法:next
和 Symbol.iterator
。
以下是实现迭代器协议的两个主要方面:
-
迭代器协议:该协议要求任何对象的
next()
方法都返回一个对象,该对象包含两个属性:value
和done
。其中,value
属性表示下一个迭代的值,done
是一个布尔值,如果迭代已经完成,则值为true
;如果迭代尚未完成,则值为false
。例如,实现一个简单的迭代器可以如下所示:
javascriptfunction createCounter(start, end) { let current = start; // 这里返回的对象符合迭代器协议 return { next() { if (current <= end) { return { value: current++, done: false }; } else { return { done: true }; } } }; } const counter = createCounter(1, 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()); // { done: true }
-
可迭代协议:该协议要求对象具有一个
Symbol.iterator
方法。这个方法必须返回一个符合迭代器协议的对象。这意味着这个方法返回一个迭代器,可用于获取对象的连续值。当使用像
for...of
这样的循环语句时,会自动寻找对象的Symbol.iterator
方法来获取迭代器,然后通过这个迭代器进行迭代。下面是一个实现可迭代协议的例子:
javascriptclass RangeIterator { constructor(start, end) { this.current = start; this.end = end; } [Symbol.iterator]() { return this; } next() { if (this.current <= this.end) { return { value: this.current++, done: false }; } else { return { done: true }; } } } for (const num of new RangeIterator(1, 3)) { console.log(num); // 依次打印出 1, 2, 3 }
在上述的 RangeIterator
类中,我们实现了 Symbol.iterator
方法并且让它返回 this
,即它自身是一个迭代器。此外,我们也实现了 next()
方法来满足迭代器协议。
通过这样的机制,ES6 不仅让内置对象如数组和字符串成为可迭代对象,也允许开发者自定义迭代行为,这在处理自定义数据结构时非常有用。