码迷,mamicode.com
首页 > 其他好文 > 详细

ECMAScript6 - Iterators and Generators

时间:2015-03-17 17:39:04      阅读:144      评论:0      收藏:0      [点我收藏+]

标签:

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-生成器函数表达式

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

 

ECMAScript6 - Iterators and Generators

标签:

原文地址:http://www.cnblogs.com/avivaWang/p/4344551.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!