ES6之Iterator 和 for...of 循环

一、概念

遍历器(Iterator)是一种接口,为各种不同的数据结构提供统一的访问机制。任何数据结构只要部署 Iterator 接口,就可以完成遍历操作(即依次处理该数据结构的所有成员)。

  • 作用:
    1)为各种数据结构,提供一个统一的、简便的访问接口;
    2)使得数据结构的成员能够按某种次序排列;
    3) ES6 创造了一种新的遍历命令for...of循环,Iterator 接口主要供for...of消费。
  • 实质:
    Iterator创建一个指针对象,指向当前数据结构的起始位置,不断调用指针对象的next方法直到数据结构结束位置,遍历事先给定的数据结构
var it = makeIterator(['a', 'b']);

it.next() // { value: "a", done: false }
it.next() // { value: "b", done: false }
it.next() // { value: undefined, done: true }

function makeIterator(array) {
  var nextIndex = 0;
  return {
    next: function() {
      return nextIndex < array.length ?
        {value: array[nextIndex++], done: false} :
        {value: undefined, done: true};
    }
  };
}

二、 Symbol.iterator属性:

一个数据结构只要具有Symbol.iterator属性,就可以认为是“可遍历的

const obj = {
  [Symbol.iterator] : function () {
    return {
      next: function () {
        return {
          value: 1,
          done: true
        };
      }
    };
  }
};

原生具备 Iterator 接口的数据结构如下:

  • Array
  • Map
  • Set
  • String
  • TypedArray
  • 函数的 arguments 对象
  • NodeList 对象

对象(Object)之所以没有默认部署 Iterator 接口,是因为对象的哪个属性先遍历,哪个属性后遍历是不确定的,需要开发者手动指定。

三、遍历器对象的 return(),throw()

遍历器对象的next()方法是必须部署的,return()方法(必须返回一个对象)和throw()方法是否部署是可选的。return()方法的使用场合是,如果for...of循环提前退出,就会调用return()方法。如果一个对象在完成遍历前,需要清理或释放资源,就可以部署return()方法

function readLinesSync(file) {
  return {
    [Symbol.iterator]() {
      return {
        next() {
          return { done: false };
        },
        return() {
          file.close();
          return { done: true };
        }
      };
    },
  };
}

throw()方法主要是配合 Generator 函数使用,一般的遍历器对象用不到这个方法。

四、for...of 循环

for...of循环内部调用的是数据结构的Symbol.iterator方法,for...in循环,只能获得对象的键名,for...of循环,允许遍历获得键值

const arr = ['red', 'green', 'blue'];

for(let v of arr) {
  console.log(v); // red green blue
}

对于普通的对象,for...of结构不能直接使用,会报错,必须部署了 Iterator 接口后才能使用,可以使用for...in循环遍历键名

let es6 = {
  edition: 6,
  committee: "TC39",
  standard: "ECMA-262"
};

for (let e in es6) {
  console.log(e);
}
// edition
// committee
// standard

for (let e of es6) {
  console.log(e);
}
// TypeError: es6[Symbol.iterator] is not a function

你可能感兴趣的:(ES6之Iterator 和 for...of 循环)