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

  1. 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}
  1. 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'
}
  1. 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
}
  1. 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

  1. for...of loops
const arr = [1, 2, 3]
for (const item of arr) {
  console.log(item)
}
  1. Spread Operator
const set = new Set([1, 2, 3])
console.log([...set]) // [1, 2, 3]
  1. Destructuring Assignment
const [first, second] = 'hello'
console.log(first, second) // 'h', 'e'
  1. 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.

相似文章
相似文章
 全屏