蘑小De菇

个人技术博客

hi,我是蘑小De菇,一名前端开发者。


记录个人对技术的理解和开发过程中遇到的问题,欢迎了解更多。

迭代器

迭代器是一种一次性使用的对象,用于迭代与其关联的可迭代对象

迭代器模式

把某些结构成为可迭代对象,因为它们实现了iterable接口,且可被迭代器iterator消费。

可迭代对象:集合类型的对象,具有有限的元素

默认迭代器 [Symbol.iterator]

调用这个工厂函数会生成一个迭代器

const arr = new Array()
arr[Symbol.iterator]()  // ArrayIterator

实现iterable接口的数据类型

如果对象的父类实现了iterable接口,那这个对象也实现了这个接口

  • 字符串
  • 数组
  • Set
  • Map
  • arguments
  • NodeList对象(dom)
  • 生成器对象

接收可迭代对象的原生语言特性包括

  • for-of循环
  • 数组解构
  • 扩展操作符
  • Array.from()
  • 创建Map
  • 创建Set
  • Promise.all()
  • Promise.race()
  • yield* 操作符

迭代器

  • 迭代器维护一个可迭代对象的引用,所以迭代器会阻止垃圾回收机构回收可迭代对象
  • 不同迭代器的实例相互之间没有联系
  • 可迭代对象在迭代期间被修改,迭代器也会相应变化。

迭代器工作原理

  • 创建一个指针对象,指向数据结构的起始位置
  • 第一次调用next(),迭代器将指针指向第一个成员
  • 接下来每次调用next()接口,指针都会向后移动,直到最后一个成员
  • 每次调用next()方法都会返回一个属性为done、value的对象,{value: 当前成员的值,done: 布尔值}
    • value表示当前成员的值,done对应的布尔值表示当前的数据的结构是否遍历结束。
    • 当遍历结束的时候返回的value值是undefined,done值为true

自定义迭代器

// 函数
function iteratorFun(arr) {
    let nextIndex = 0
    return {
        next: function () {
            return nextIndex < arr.length
                ? { value: arr[nextIndex++], done: false }
                : { value: undefined, done: true }
        }
    }
}

let objIterator = new iteratorFun([1, 2, 3])
console.log(objIterator.next())
console.log(objIterator.next())
console.log(objIterator.next())
console.log(objIterator.next())

// { value: 1, done: false }
// { value: 2, done: false }
// { value: 3, done: false }
// { value: undefined, done: true }

// class

class Iterator {
    constructor(arr) {
        this.arr = arr
    }

    [Symbol.iterator]() {
        let count = 0, arr = this.arr;
        return {
            next() {
                return count < arr.length ? { value: arr[count++], done: false } : { value: undefined, done: true }
            }
        }
    }
}


let iterator = new Iterator([1, 2, 3]);

// console.log(iterator[Symbol.iterator]().next())

for (let i of iterator) {
    console.log(i)
}


提前终止迭代器

  • for-of循环可通过return、break、continue、throw 提前退出

  • 数组迭代器是不能关闭的

      let arr = [1,2,3,4,5,6]
      let iter = arr[Symbol.iterator]()
    
      for(let i of iter) {
          if(i>2) {
              break
          }
      }
      // 1,2,3
    
      for(let i of iter) {
          console.log(i)
      }
      // 4,5
    
下一篇

生成器

上一篇

weakMap & weakSet