ECMAScript 6 迭代器协议(Iteration protocols)

 2015年11月09日    437     声明


ECMAScript 6增加了一个对象,它不是新的语法或新的内置对象,而一种协议( 迭代器协议),所有遵守这个协议的对象,都可以称之为迭代器迭代器用于遍历对象中的元素,所以又可以称之为遍历器

  1. 可迭代协议(iterable protocol
  2. 迭代器协议(iterator protocol
  3. 使用迭代器协议


ES6迭代器协议由两部分组成:可迭代协议(iterable protocol)和迭代器协议(iterator protocol)。

1. 可迭代协议(iterable protocol

可迭代协议允许JavaScript对象去定义或者自定义迭代形为,如:什么样的值可以在for..of循环中构建。一些内置类型内置了有默认迭代形为的迭代对象,如:ArrayMap,其它类型(如:Object)则没有。

要使对象是可迭代的,那么必须实现@@iterator方法,即,对象(或对象原型链)必须有一个Symbol.iterator键属性:

属性
[Symbol.iterator] 一个包含0个参数的函数,该函数返回一个满足迭代器协议的对象

每当一个对象需要进行迭代(如,开始for..of循环),它的@@iterator方法就会以无参数的形式被调用,返回的迭代器用于获得迭代的值。


2. 迭代器协议(iterator protocol

迭代器协议定义了一个标准的方法用来产生一系列的值(无论是有限的还是无限的)。

一个对象,当具有以下next()方法的实现时,那么它就可以是一个迭代器:

属性
next

一个具有0个参数的函数,返回一个包含以下两个属性的对象:

  • done (boolean)
    • 当迭代器迭代完成,则返回 true
    • 如果迭代器还有下一个值,则返回 false
  • value-由迭代器返回的值,当done属性为true时可以忽略。


3. 使用迭代器协议

字符串就是一个内置的可迭代的对象实例:

var someString = "hi";
typeof someString[Symbol.iterator];          // "function"

字符串的默认迭代器会依次返回字符串中的字符:

var iterator = someString[Symbol.iterator]();
iterator + "";          // "[object String Iterator]"
 
iterator.next();        // { value: "h", done: false }
iterator.next();        // { value: "i", done: false }
iterator.next();        // { value: undefined, done: true }

我们可以重定义迭代器,使其具有新行为:

var someString = new String("hi");

someString[Symbol.iterator] = function() {
  return { // 这个迭代器在第一个字符时会返回:"itbilu.com"
    next: function() {
      if (this._first) {
        this._first = false;
        return { value: "itbilu.com", done: false };
      } else {
        return { done: true };
      }
    },
    _first: true
  };
};