ECMAScript6 - Iterators and Generators

Iterators and Generators

Iterators have been used in many programming languages as a way to more easily work with collections of data. In ECMAScript 6, JavaScript adds iterators as an important feature of the language. When coupled with new array methods and new types of collections (such as sets and maps), iterators become even more important for efficient processing of data.

  在其他的语言中,遍历器被用来更加方便的处理数据集合。在ES6中,js增加了遍历器作为这个语言的重要特征。当结合新的数组方法和新的集合类型(例如set和map),因为高效的处理数据的能力,遍历器变得更加重要。

What are Iterators?-什么是遍历器

Iterators are nothing more than objects with a certain interface. That interface consists of a method called next() that returns a result object. The result object has two properties, value, which is the next value, and done, which is a boolean value that’s true when there are no more values to return. The iterator keeps an internal pointer to a location within a collection of values and, with each call to next(), returns the next appropriate value.

  遍历器只是一个拥有特定接口的对象。这个接口包含了一个方法叫做next()可以返回结果对象。结果对象有两个属性:value-next的值,和done-布尔值,为true的时候表示下一次将没有返回值。遍历器有一个内部指针来定位集合的值,每次调用next方法,都返回下一个适当的值。

If you call next() after the last value has been returned, the method returns done as true and value contains the return value for the iterator. The return value is not considered part of the data set, but rather a final piece of related data or undefined if no such data exists. (This concept will become clearer in the generators section later in this chapter.)

  如果在返回最后一个值之后又调用了next(),这个方法返回的done的值为true,value包含了遍历器的返回值,返回值不是集合的一部分,而是最后一个相关的数据或者undefined如果没定义这个数据。

With that understanding, it’s fairly easy to create an iterator using ECMAScript 5, for example:

  理解到这,使用ES5创建一个遍历器也很简单,例如:

function createIterator(items) {

    var i = 0;

    return {
        next: function() {

            var done = (i >= items.length);
            var value = !done ? items[i++] : undefined;

            return {
                done: done,
                value: value
            };

        }
    };
}

var iterator = createIterator([1, 2, 3]);

console.log(iterator.next());           // "{ value: 1, done: false }"
console.log(iterator.next());           // "{ value: 2, done: false }"
console.log(iterator.next());           // "{ value: 3, done: false }"
console.log(iterator.next());           // "{ value: undefined, done: true }"

// for all further calls
console.log(iterator.next());           // "{ value: undefined, done: true }"

The createIterator() function in this example returns an object with a next() method. Each time the method is called, the next value in the items array is returned as value. When i is 4, items[i++] returns undefined and done is true, which fulfills the special last case for iterators in ECMAScript 6.

  本例中的createIterator函数返回了一个拥有next方法的对象。每当这个方法调用的时候,items数组中的下一个值作为value属性返回。当i等于4的时候,item[i++]返回undefined和done的值为true,符合ES6中的遍历器特性。

ECMAScript 6 makes use of iterators in a number of places to make dealing with collections of data easier, so having a good basic understanding allows you to better understand the language as a whole.

  ES6中在很多地方使用遍历器来处理集合数据更加方便,所以拥有良好的理解可以让你更好的理解整个语言。

Generators-生成器

You might be thinking that iterators sound interesting but they look like a bunch of work. Indeed, writing iterators so that they adhere to the correct behavior is a bit difficult, which is why ECMAScript 6 provides generators. A generator is a special kind of function that returns an iterator. Generator functions are indicated by inserting a star character (*) after the function keyword (it doesn’t matter if the star is directly next to function or if there’s some whitespace between them). The yield keyword is used inside of generators to specify the values that the iterator should return when next() is called. So if you want to return three different values for each successive call to next(), you can do so as follows:

  你可能在想,遍历器听起来很有意思,但是它们需要很多的工作。确实,编写一个确保行为正确的遍历器有点困难,这就是为什么ES6引入了generators(生成器),一个generators是一个能够返回遍历器的特殊函数。生成器在function关键字之后增加一个星字符(*)来表示(星字符与function关键字之间是否又空格没有影响)。yield关键字用在生成器内部来制定当遍历器的next方法调用的时候应该返回什么值。所以如果你想每次调用next的时候返回三个不同的值,你可以像下面这样做:

// generator
function *createIterator() {
    yield 1;
    yield 2;
    yield 3;
}

// generators are called like regular functions but return an iterator
let iterator = createIterator();

for (let i of iterator) {
    console.log(i);
}

This code outputs the following:

这段代码的输出如下:

1
2
3

In this example, the createIterator() function is a generator (as indicated by the * before the name) and it’s called like any other function. The value returned is an object that adheres to the iterator pattern. Multiple yield statements inside the generator indicate the progression of values that should be returned when next() is called on the iterator. First, next() should return 1, then 2, and then 3 before the iterator is finished.

  在这个例子中,createIterator函数是一个生成器(函数名字之前有星字符),它的调用和其他函数一样。返回的值是一个遍历器形式的对象。生成器内部的多个yield声明表示当调用遍历器的next方法的时候这些值会依次被返回。第一次next返回1,然后是2和3.

Perhaps the most interesting aspect of generator functions is that they stop execution after each yield statement, so yield 1 executes and then the function doesn’t execute anything else until the iterator’s next() method is called. At that point, execution resumes with the next statement after yield 1, which in this case is yield 2. This ability to stop execution in the middle of a function is extremely powerful and lends to some interesting uses of generator functions (discussed later in this chapter).

  也许生成器最有趣的一方面在于每次yield声明执行之后,生成器函数就会停止执行,所以yield 1 执行了知道遍历器的next方法被调用之前这个函数都不会继续往下执行。对于这一点,在yeild声明之后恢复执行,本例中也就是yield2.在函数内部停止执行的能力很强大,这导致了生成器函数的很多有意思的用途。(稍后讨论)

The yield keyword can be used with any value or expression, so you can do interesting things like use yield inside of a for loop:

  yield关键字可以和任何的值和表达式一起使用,所以在for循环中你可以使用yield来做一个有趣的事:

function *createIterator(items) {
    for (let i=0; i < items.length; i++) {
        yield items[i];
    }
}

let iterator = createIterator([1, 2, 3]);

console.log(iterator.next());           // "{ value: 1, done: false }"
console.log(iterator.next());           // "{ value: 2, done: false }"
console.log(iterator.next());           // "{ value: 3, done: false }"
console.log(iterator.next());           // "{ value: undefined, done: true }"

// for all further calls
console.log(iterator.next());           // "{ value: undefined, done: true }"

In this example, an array is used in a for loop, yielding each item as the loop progresses. Each time yield is encountered, the loop stops, and each time next() is called on iterator, the loop picks back up where it left off.

  在这个例子中,循环一个数组,每次循环都输出数组的一项。每次遇到yield,循环停止,每次调用遍历器的next方法,循环都会从之前停止的地方开始。

Generator functions are an important part of ECMAScript 6, and since they are just functions, they can be used in all the same places.

  生成器是ES6 重要的一部分,因为他们只是函数,所以他们和函数的用法一样。

Generator Function Expressions-生成器函数表达式

未完待续。。。。(翻译也是一个挺累的活计)

时间: 2024-10-31 01:33:07

ECMAScript6 - Iterators and Generators的相关文章

Python高级特性(1):Iterators、Generators和itertools(转)

译文:Python高级特性(1):Iterators.Generators和itertools [译注]:作为一门动态脚本语言,Python 对编程初学者而言很友好,丰富的第三方库能够给使用者带来很大的便利.而Python同时也能够提供一些高级的特性方便用户使用更为复杂的数据结构.本系 列文章共有三篇,本文是系列的第一篇,将会介绍迭代器.生成器以及itertools模块的相关用法.由于作者 Sahand Saba 列举的示例中有诸多专业的数学相关内容,因此翻译中有诸多不妥之处请大家指出,非常感谢

Iterables vs. Iterators vs. Generators(可迭代对象,迭代器,生成器)

原文出处:Iterables vs. Iterators vs. Generators 在python学习中,通常会陷入对以下几个相关概念之间的确切不同点的困惑中: a container(容器) an iterable(可迭代对象) an iterator(迭代器) a generator(生成器) a generator expression(生成表达式) a {list, set, dict} comprehension(列表/集合/字典推导式) 原文地址:https://www.cnbl

Python标准模块--Iterators和Generators

1 模块简介 当你开始使用Python编程时,你或许已经使用了iterators(迭代器)和generators(生成器),你当时可能并没有意识到.在本篇博文中,我们将会学习迭代器和生成器是什么.当然,我们也会了解如何创建它们,在我们需要的时候,就可以创建属于我们自己的迭代器和生成器. 2 模块使用 2.1 迭代器 迭代器是一个允许你在一个容器上进行迭代的对象.Python的迭代器主要通过两个方法实现:__iter__和__next__.__iter__要求你的容器支持迭代.它会返回迭代器对象本

Python高级特性(1):Iterators、Generators和itertools(参考)

对数学家来说,Python这门语言有着很多吸引他们的地方.举几个例子:对于tuple.lists以及sets等容器的支持,使用与传统数学类 似的符号标记方式,还有列表推导式这样与数学中集合推导式和集的结构式(set-builder notation)很相似的语法结构. 另外一些很吸引数学爱好者的特性是Python中的iterator(迭代器).generator(生成器)以及相关的itertools包.这 些工具帮助人们能够很轻松的写出处理诸如无穷序列(infinite sequence).随机

ECMAScript6 -Symbols

Symbols-标志 ECMAScript 6 symbols began as a way to create private object members, a feature JavaScript developers have long wanted. The focus was around creating properties that were not identified by string names. Any property with a string name was

25.参考链接

参考链接 参考链接 官方文件 ECMAScript? 2015 Language Specification: ECMAScript 2015 规格 ECMAScript? 2016 Language Specification: ECMAScript 2016 规格 ECMAScript? 2017 Language Specification:ECMAScript 2017 规格(草案) ECMAScript Current Proposals: ECMAScript 当前的所有提案 ECM

编程思想之迭代器

原文:http://blog.csdn.net/luoweifu/article/details/42472303 什么是迭代器? 迭代器(Iterator)是按照一定的顺序对一个或多个容器中的元素从前往遍历的一种机制,比如for循环就是一种最简单的迭代器,对一个数组的遍历也是一种的迭代遍历的过程.GOF给出的定义为:提供一种方法访问一个容器(container)对象中各个元素,而又不需暴露该对象的内部细节.迭代器有时也称为枚举器(Enumerator),其结构图如下: 迭代器结构图 迭代器其实

使用Python实现Hadoop MapReduce程序

转自:使用Python实现Hadoop MapReduce程序 英文原文:Writing an Hadoop MapReduce Program in Python 根据上面两篇文章,下面是我在自己的ubuntu上的运行过程.文字基本采用博文使用Python实现Hadoop MapReduce程序,  打字很浪费时间滴. 在这个实例中,我将会向大家介绍如何使用Python 为 Hadoop编写一个简单的MapReduce程序. 尽管Hadoop 框架是使用Java编写的但是我们仍然需要使用像C+

Python学习之旅—Day07(生成器与迭代器)

前言 本篇博客主要专注于解决函数中的一个重要知识点--生成器与迭代器.不管是面试还是工作,生成器与迭代器在实际工作中的运用可以说是非常多,从我们第一天开始学习for循环来遍历字典,列表等数据类型时,我们就已经和生成器,迭代器打交道了!本篇博客从最基础的基本概念,例如容器,可迭代对象,生成器,迭代器的概念,到for循环是怎么工作的娓娓道来.希望本篇博客能够帮助大家切实掌握生成器与迭代器的使用与底层原理. 一.容器 容器是一种把多个元素组织在一起的数据结构,容器中的元素可以逐个地迭代获取,可以用in