迭代器

48 阅读1分钟

任何数据结构只要部署了Iterator接口,就可以使用for…of 来遍历

具备iterator接口的数据类型

  • Array
  • Argunments
  • Set
  • Map
  • String
  • TypedArray
  • NodeList 这个接口就是对象里面的一个属性,属性的名字叫Symbol.iterator,也可以自己对结构进行布置iterator接口

工作原理

  • 先创建一个指针对象,指向当前数据结构的起始位置

  • 第一次调用对象的next方法,指针自动指向数据结构的第一个成员

  • 接下来不断调用next方法,指针一直往后移动,直到指向最后一个成员

  • 每次调用next方法就会返回一个包含value和done属性(是否完成)的对象

  • 上面给大家举例了很多可迭代对象,那它们必定是符合可迭代对象协议的,思考以下代码

      const bears = ['ice', 'panda', 'grizzly']
//数组的Symbol.iterator方法
const iter = bears[Symbol.iterator]()

console.log(iter.next())
console.log(iter.next())
console.log(iter.next())
console.log(iter.next())


const nickName = 'ice'
//字符串的Symbol.iterator方法
const strIter = nickName[Symbol.iterator]()

console.log(strIter.next())
console.log(strIter.next())
console.log(strIter.next())
console.log(strIter.next())

可迭代对象的实现

   let info = {
  bears: ['ice', 'panda', 'grizzly'],
  [Symbol.iterator]: function() {
    let index = 0
    let _iterator = {
       //这里一定要箭头函数,或者手动保存上层作用域的this
       next: () => {
        if (index < this.bears.length) {
          return { done: false, value: this.bears[index++] }
        }
  
        return { done: true, value: undefined }
      }
    }

    return _iterator
  }
}

let iter = info[Symbol.iterator]()
console.log(iter.next())
console.log(iter.next())
console.log(iter.next())
console.log(iter.next())

//符合可迭代对象协议 就可以利用 for of 遍历
for (let bear of info) {
  console.log(bear)
}
//ice panda grizzly

  • 符合可迭代对象协议,是一个对象,有[Symbol.iterator]方法,并且这个方法返回了一个迭代器对象。
  • 当我利用for of 遍历,就会自动的调用这个方法
  • 当使用扩展运算符(...)或者对数组和 Set 结构进行解构赋值时,会默认调用Symbol.iterator方法
let arr1 = [1,3]
let arr2 = [2,3,4,5]
arr2 = [1,...arr2,6]
console.log(arr2) // [1, 2, 3, 4, 5, 6]

迭代器的封装实现

        const bears = ['ice', 'panda', 'grizzly']

        function createArrIterator(arr) {
        let index = 0

        let _iterator = {
            next() {
            if (index < arr.length) {
                return { done: false, value: arr[index++] }
            }

            return { done: true, value: undefined }
            }
        }

        return _iterator
        }

        let iter = createArrIterator(bears)

        console.log(iter.next())
        console.log(iter.next())
        console.log(iter.next())
        console.log(iter.next())

自定义类迭代实现

class myInfo {
  constructor(name, age, friends) {
    this.name = name
    this.age = age
    this.friends = friends
  }

  [Symbol.iterator]() {
    let index = 0
    // console.log(this);
    let _iterator = {
      next: () => {
        const friends = this.friends
        if (index < friends.length) {
          return {done: false, value: friends[index++]}
        }

        return {done: true, value: undefined}
      }
    }

    return _iterator
  }
}

const info = new myInfo('ice', 22, ['panda','grizzly'])

for (let bear of info) {
  console.log(bear)
}

//panda
//grizzly
  • 此案例只是简单的对friends进行了迭代,你也可以迭代你想要的一切东西...