深入理解ES6读书笔记7:迭代器与生成器

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

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()); // "{done: false, value: 1}"
console.log(iterator.next()); // "{done: false, value: 2}"
console.log(iterator.next()); // "{done: false, value: 3}"
console.log(iterator.next()); // "{done: true, value: undefined}"

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

生成器是能返回一个迭代器的函数。
生成器函数由放在function关键字之后的一个星号(*)来表示,并能使用新的yield关键字。
yield指定了迭代器在被next() 方法调用时应当按顺序返回的值。

function *createIterator(items) {
    for (let i = 0; i < items.length; i++) {
        yield items[i];
    }
}
//创建生成器也可以使用生成器函数表达式,上面第一行代码改成
//let createIterator = function *(items) {

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

生成器就是函数,可以被添加到对象中。

var o = {
    //ES5中使用函数表达式创建生成器,如果是ES6中第一行可以简化成*createIterator(items) {
    createIterator: function *(items) {
        for (let i = 0; i < items.length; i++) {
            yield items[i];
        }
    }    
};
let iterator = o.createIterator([1, 2, 3]);

可迭代对象与 for-of 循环

可迭代对象是包含 Symbol.iterator 属性的对象。
ES6 中,所有的集合对象(数组、Set与Map)以及字符串都是可迭代对象,因此它们都被指定了默认的迭代器。
可迭代对象被设计用于与 ES 新增的 for-of 循环配合使用。
for-of 循环在循环每次执行时会调用可迭代对象的 next() 方法,并将结果对象的 value
值存储在一个变量上。循环过程会持续到结果对象的 done 属性变成 true 为止。

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

使用Symbol.iterator访问对象的默认迭代器

let values = [1, 2, 3];
let iterator = values[Symbol.iterator]();
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}"

集合的迭代器

集合的3种对象类型:数组、Map与Set都拥有如下的迭代器:
entries() :返回一个包含键值对的迭代器;
values() :返回一个包含集合中的值的迭代器;
keys() :返回一个包含集合中的键的迭代器。
当 for-of 循环没有显式指定迭代器时,每种集合类型都有一个默认的迭代器供循环使用。
values() 方法是数组与 Set 的默认迭代器,而 entries() 方法则是 Map 的默认迭代器。

let colors = [ "red", "green", "blue" ];
for (let entry of colors.entries()) {
    console.log(entry);
}
/*输出:
[0, "red"]
[1, "green"]
[2, "blue"]
*/
for (let entry of colors.values()) {
    console.log(entry);
}
/*输出:
"red"
"green"
"blue"
*/
for (let key of colors.keys()) {
    console.log(key);
}
/*输出:
0
1
2
*/
for (let entry of colors) {
    console.log(entry);
}
/*输出:
"red"
"green"
"blue"
*/

解构与 for-of 循环

Map 默认迭代器的行为有助于在 for-of 循环中使用解构。

let data = new Map();
data.set("title", "Understanding ES6");
data.set("format", "ebook");
// 与使用 data.entries() 相同
for (let [key, value] of data) {
    console.log(key + "=" + value);
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值