Iteration Protocols and Iterable Objects in JavaScript
字数 1413
更新时间 2025-11-12 17:24:05
Iteration Protocols and Iterable Objects in JavaScript
Iteration protocols are a set of rules introduced in ES6 that define how data structures can be traversed. There are two protocols: the iterable protocol and the iterator protocol.
Iterable Protocol
- For an object to implement the iterable protocol, it must include a special property:
Symbol.iterator - The value of this property must be a zero-argument function that, when called, returns an iterator object.
Iterator Protocol
- An iterator is an object that implements a
next()method. - The
next()method must return an object containing two properties:value: The current value of the iteration.done: A boolean value indicating whether the iteration is complete.
Detailed Implementation Process
- Basic Iterator Implementation
// Create a simple iterator
const simpleIterator = {
data: [1, 2, 3],
index: 0,
next() {
if (this.index < this.data.length) {
return { value: this.data[this.index++], done: false }
} else {
return { value: undefined, done: true }
}
}
}
console.log(simpleIterator.next()) // {value: 1, done: false}
console.log(simpleIterator.next()) // {value: 2, done: false}
console.log(simpleIterator.next()) // {value: 3, done: false}
console.log(simpleIterator.next()) // {value: undefined, done: true}
- Implementing an Iterable Object
// Create an iterable object
const myIterable = {
data: ['a', 'b', 'c'],
// Implement the Symbol.iterator method
[Symbol.iterator]() {
let index = 0
const data = this.data
// Return the iterator object
return {
next() {
if (index < data.length) {
return { value: data[index++], done: false }
} else {
return { value: undefined, done: true }
}
}
}
}
}
// Test the iterable object
for (const item of myIterable) {
console.log(item) // Outputs sequentially: 'a', 'b', 'c'
}
- Using Generator Functions for Simplified Implementation
const myIterableWithGenerator = {
data: [10, 20, 30],
// More concise using a generator function
*[Symbol.iterator]() {
for (const item of this.data) {
yield item
}
}
}
// Same effect
for (const num of myIterableWithGenerator) {
console.log(num) // 10, 20, 30
}
- Custom Range Iterator
// Create an iterable object for a number range
class NumberRange {
constructor(start, end, step = 1) {
this.start = start
this.end = end
this.step = step
}
*[Symbol.iterator]() {
let current = this.start
while (this.step > 0 ? current <= this.end : current >= this.end) {
yield current
current += this.step
}
}
}
// Usage example
const range = new NumberRange(1, 5)
console.log([...range]) // [1, 2, 3, 4, 5]
const reverseRange = new NumberRange(5, 1, -1)
console.log([...reverseRange]) // [5, 4, 3, 2, 1]
Built-in Iterable Objects
- Array, String, Map, Set, TypedArray, the arguments object
- DOM collections like NodeList
Use Cases
- for...of loops
const arr = [1, 2, 3]
for (const item of arr) {
console.log(item)
}
- Spread Operator
const set = new Set([1, 2, 3])
console.log([...set]) // [1, 2, 3]
- Destructuring Assignment
const [first, second] = 'hello'
console.log(first, second) // 'h', 'e'
- Array.from()
const map = new Map([['a', 1], ['b', 2]])
console.log(Array.from(map)) // [['a', 1], ['b', 2]]
Important Notes
- Iterators are one-way and can only be traversed once.
- They can be called manually for more granular control.
- Generator functions inherently return an iterable object.
Understanding iteration protocols helps in creating custom data structures that integrate seamlessly with JavaScript's iteration mechanisms.
相似文章
相似文章