A-A+

迭代器与生成器(Iterators and Generators)

2017年08月27日 JavaScript 暂无评论

前言

for循环存在问题。
遍历器(Iterator)就是这样一种机制。它是一种接口,为各种不同的数据结构提供统一的访问机制。任何数据结构只要部署Iterator接口,就可以完成遍历操作(即依次处理该数据结构的所有成员)。
Iterator的作用有三个:一是为各种数据结构,提供一个统一的、简便的访问接口;二是使得数据结构的成员能够按某种次序排列;三是ES6创造了一种新的遍历命令for…of循环,Iterator接口主要供for…of消费。

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};
    }
  };
}

Iterator只是把接口规格加到数据结构之上,所以,遍历器与它所遍历的那个数据结构,实际上是分开的
Iterator接口的目的,就是为所有数据结构,提供了一种统一的访问机制,即for…of循环。当使用for…of循环遍历某种数据结构时,该循环会自动去寻找Iterator接口。

一种数据结构只要部署了Iterator接口,我们就称这种数据结构是”可遍历的“(iterable)。

生成器

生成器是返回迭代器的函数。生成器函数由 function 关键字和之后的星号()标识,同时还能使用新的 yield 关键字。星号的位置不能论是放在 function 关键字的后面还是在它们插入空格都是随意的。
生成器函数在运行时能被中断执行
*
yield 关键字只能用在生成器内部。在其它地方甚至是生成器内部的函数中使用都会抛出语法错误**

function *createIterator(items) {
    items.forEach(function(item) {
        // 语法错误
        yield item + 1;
    });
}

无法使用箭头函数来创建生成器。

for of

for-lof 循环会在可迭代类型每次迭代执行后调用 next() 并将结果对象存储在变量中。循环会持续进行直到结果对象的 done 属性为 true

let values = [1, 2, 3];

for (let num of values) {
    console.log(num);
}
1
2
3

如果只想简单的迭代数组或集合中的元素, for-of 循环比 for 要更好.

内置的迭代器

ECMAScript 6 内置了三种类型的集合对象:数组,map 和 set 。它们都有如下内置的迭代器供你浏览数据。entries() - 返回一个数据集为集合中的键值对的迭代器
values() - 返回一个数据集为集合中的的迭代器
keys() - 返回一个数据集为集合中的的迭代器

let colors = [ "red", "green", "blue" ];
let tracking = new Set([1234, 5678, 9012]);
let data = new Map();

data.set("title", "Understanding ECMAScript 6");
data.set("format", "ebook");

for (let entry of colors.entries()) {
    console.log(entry);
}

for (let entry of tracking.entries()) {
    console.log(entry);
}

for (let entry of data.entries()) {
    console.log(entry);
}

[0, "red"]
[1, "green"]
[2, "blue"]
[1234, 1234]
[5678, 5678]
[9012, 9012]
["title", "Understanding ECMAScript 6"]
["format", "ebook"]

每种集合类型都包含一个默认的迭代器以供 for-of 循环显式或隐式的使用。数组和 set 默认的迭代器是 values() 方法,而 map 则是 entries() 。这些默认设定能方便 for-of 循环迭代集合对象.
NodeList 的迭代器和数组的默认迭代器行为是一致的。

var divs = document.getElementsByTagName("div");

for (let div of divs) {
    console.log(div.id);
}

todo 异步

标签:

给我留言

Copyright © 花未全开月未圆 保留所有权利.   Theme  Ality 海外

用户登录