十一、Iterator迭代器

郁子大约 2 分钟约 594 字笔记ECMAScript尚硅谷李强

(一)Iterator 简介

  • Iterator 是一种接口【即对象的属性】
    • 为各种不同的数据结构提供统一的访问机制
    • 任何数据结构只要部署 iterator 接口就可以完成遍历操作
  • ES6创造了一种新的遍历命令 for...of 循环
    • iterator 主要供 for...of 消费
  • 原生具备 iterator 接口的数据(即可用 for...of 遍历)
    • Array
    • Arguments
    • Set
    • Map
    • String
    • TypeArray
    • NodeList
  • 需要自定义遍历数据的时候,要想到迭代器
// 声明一个数组
const xiyou = ["唐僧", "孙悟空", "猪八戒", "沙僧"];

// 使用for...in遍历【遍历的是键名】
for (let k in xiyou) {
  console.log(k);
}
// 0
// 1
// 2
// 3

// 使用for...of遍历【遍历的是键值】
for (let v of xiyou) {
  console.log(v);
}
// 唐僧
// 孙悟空
// 猪八戒
// 沙僧

// 数组可以遍历是因为原型对象上有Symbol(Symbol.iterator): ƒ values()
console.log(xiyou);

(二)工作原理

  • 创建一个指针对象,指向当前数据结构的起始位置
  • 第一次调用对象的 next 方法,指针自动指向数据结构的第一个成员
  • 接下来不断调用 next 方法,指针一直往后移动,直到指向最后一个成员
  • 每调用一次 next 方法返回一个包含 valuedone 属性的对象
let iterator = xiyou[Symbol.iterator]();
console.log(iterator);
// Array Iterator {}  原型里有next()

// 调用对象的next方法
console.log(iterator.next());
// {value: '唐僧', done: false}
console.log(iterator.next());
// {value: '孙悟空', done: false}
console.log(iterator.next());
// {value: '猪八戒', done: false}
console.log(iterator.next());
// {value: '沙僧', done: false}
console.log(iterator.next());
// {value: undefined, done: true}

(三)自定义遍历数据

  • 需求:使用 for...of 遍历这个对象,返回结果是 stus 数组的一个成员

1.banji.stus.forEach()

  • 可以实现,但是不符合面向对象的思想,
    • 最好不要直接操作对象中的属性
  • 应该通过对象暴露出来的方法获得相应的属性
// 声明一个对象
const banji = {
  name: "终极一班",
  stus: ["xiaoming", "xiaoning", "xiaotian", "knight"],
};

for (let v of banji) {
  console.log(v);
}
// banji is not iterable

2.Symbol.iterator

// 声明一个对象
const banji = {
  name: "终极一班",
  stus: ["xiaoming", "xiaoning", "xiaotian", "knight"],
  [Symbol.iterator]() {
    // 索引变量
    let index = 0;
    return {
      next: () => {
        if (index < this.stus.length) {
          const res = {
            value: this.stus[index],
            done: false,
          };
          index++;
          return res;
        } else {
          return {
            value: undefined,
            done: true,
          };
        }
      },
    };
  },
};

for (let v of banji) {
  console.log(v);
}
// xiaoming
// xiaoning
// xiaotian
// knight
上次编辑于: