ES6(八)迭代器与生成器1

迭代数据的方式从使用 for 循环转变到使用迭代器对象,

 for 循环需要 初始化变量以便追踪集合内的位置,

而迭代器则以编程方式返回集合中的下一个项。

迭代器 能使操作集合变得更简单。

当新的数组方法与新的集合类型(例如 Set 与 Map ),迭代器就是高效数据处理的关键。

新迭代器:新增的 for-of ,扩展运算符( ... ),能让异步操作更易完成。


1.循环的问题

2.何为迭代器?

3.何为生成器?


循环的问题

var colors = ["red", "green", "blue"];

for (var i = 0, len = colors.length; i < len; i++) {

    console.log(colors[i]);

}

这个循环非常直观,然而当它被嵌套使用并要追踪多个变量时,情况就会变得非常复 杂。额外的复杂度会引发错误,而for 循环的样板性也增加了自身出错的可能性,因为相似的代码会被写在多个地方。

迭代器正是用来解决此问题的.


何为迭代器?


迭代器是被设计专用于迭代的对象,带有特定接口。所有的迭代器对象都拥有 next() 方 法,会返回一个结果对象。该结果对象有两个属性:对应下一个值的value ,以及一个布尔 类型的 done ,其值为 true 时表示没有更多值可供使用。迭代器持有一个指向集合位置的内部指针,每当调用了 next() 方法,迭代器就会返回相应的下一个值。

若你在最后一个值返回后再调用 next() ,所返回的 done  属性值会是 true ,并且 value 属性值会是迭代器自身的返回值( return value,即使用 return 语句明确返回的 值)。该“返回值”不是原数据集的一部分,却会成为相关数据的最后一个片段,或在迭代器未 提供返回值的时候使用 undefined 。迭代器自身的返回值类似于函数的返回值,是向调用者 返回信息的最后手段。


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

console.log(iterator.next());

console.log(iterator.next());

console.log(iterator.next());

console.log(iterator.next());

// 之后的所有调用

console.log(iterator.next());


根据 ES6 制定的规则来书写迭代器,是有一点复杂的。 

幸好, ES6 还提供了生成器,让创建迭代器对象变得更简单。



何为生成器?

生成器

function *createIterator() {

    yield 1;

    yield 2;

    yield 3;

}

// 生成器能像正规函数那样被调用,但会返回一个迭代器

let iterator = createIterator();


console.log(iterator.next().value);  // 1

console.log(iterator.next().value); // 2

console.log(iterator.next().value); // 3

 createIterator() 前面的星号让此函数变成一个生成器。

 yield 关键字也是 ES6 新增的, 指定了迭代器在被 next() 方法调用时应当按顺序返回的值。


调用一次next() 然后停止,直到下一次调用next()才会与运行 然后停止.


yield 关键字可以和值或是表达式一起使用.

使用for循环栗子:

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());

console.log(iterator.next());


生成器函数是 ES6 的一个重要特性,并且因为它就是函数,就能被用于所有可用函数的位置。



yield 关键字只能用在生成器内部,用于其他任意位置都是语法错误,即使在生成器内部的函数中也不行:

function *createIterator(items) {

    // 只能在此处使用 yield

    items.forEach(function(item) {

        // 语法错误

        yield item + 1;

    });

}




声明 生成器 一定要有*号

可以使用匿名函数,但不能将箭头函数创建为生成器

let createIterator = function *(items) {

    for (let i = 0; i < items.length; i++) {

        yield items[i];

    }

};

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

console.log(iterator.next());




生成器就是函数,因此也可以被添加到对象.

ES5:

var o = {

    createIterator: function *(items) {

        for (let i = 0; i < items.length; i++) {

            yield items[i];

        }

    }

};

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



使用 ES6 方法的速记法,只要在方法名之前加上一个星号( * ):

var o = {

    *createIterator(items) {

        for (let i = 0; i < items.length; i++) {

            yield items[i];

        }

    }

};

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

你可能感兴趣的:(ES6(八)迭代器与生成器1)