FionaRush / Article

Articles about technology
3 stars 0 forks source link

Iterator学习 #6

Open FionaRush opened 3 years ago

FionaRush commented 3 years ago

概念

Iterator - 遍历器 是一种接口,为各种不同的数据结构提供统一的访问机制。也就是说只要拥有了 Iterator 接口就可以完成统一访问遍历操作。

作用

  1. 为不同的数据结构提供统一的访问机制;
  2. 使得数据结构的成员能够按照某种次序排序;
  3. 为 ES6 for...of 调用。

应用

凡是部署了 Iterator 属性的数据结构,称为部署了遍历器接口。调用这个接口,会返回一个遍历器对象。

ES6 中 数组、伪数组、Set 和 Map 结构,原生具备 Iterator 接口。主要有一下应用场景:

  1. for...of;
  2. 数组解构赋值;
  3. 扩展运算符(...);
  4. yield * 是一个可遍历的结构;
  5. 数组遍历;
  6. 字符串遍历;
  7. 参数遍历;

实现

添加 Symbol.iterator 来为当前对象添加遍历器接口。 遍历器对象必须有 next 方法,还可以可选 return 方法和 throw 方法。

let obj = {
  data: ['one', 'two'],
}

  ; (function () {
    for (let i of obj) {  // TypeError: obj is not iterable
      console.log('initial i', i)
    }
  })()

obj[Symbol.iterator] = function () {
  const self = this;
  let index = 0;
  return {
    next() {
      if (index < self.data.length) {
        return {
          value: self.data[index++],
          done: false
        }
      } else {
        return {
          value: undefined,
          done: true
        }
      }
    }
  }
}
obj[Symbol.iterator] = Array.prototype[Symbol.iterator];

  ; (function () {
    for (let i of obj) {
      console.log('deal i', i) // deal i one  deal i two
    }
  })()

for...of 使用原理

for (let item of ['one', 'two']) {
  console.log('item', item);
  statements...
}

var $iterator = Array.prototype[Symbol.iterator]();
var $result = $iterator.next();
while (!$result.done) {
  item = $result.value;
  statements...
  $result = $iterator.next();
}

对于 伪数组 可以直接调用数组的 Array.prototype[Symbol.iterator] 而对于普通对象部署 Array.prototype[Symbol.iterator] 方法,并无效果


const arr = {
  0: 'one',
  1: 'two',
  length: 2
}

  (function () {
    arr[Symbol.iterator] = Array.prototype[Symbol.iterator];
    for (const i of arr) {
      console.log('arr i', i) //arr i one  arr i two
    }
  })()