/**
* 迭代器(Iterator)和 生成器(Generator)
* 用循环语句迭代数据时,必须要初始化一个变量来记录每一次迭代在数据集合中的位置,而许多编程
* 语言已经通过程序化的方式用迭代器对象返回迭代过程中的每一个元素。
*
* 迭代器的使用可以极大地简化数据操作,于是ECMAScript6也添加了迭代器的特性。新的数组方法和
* 新的集合类型 Set 和 Map 都依赖于迭代器的实现
*
*/
// 1. 循环语句的问题
var colors = ["red", "blue", "green"];
for (var i = 0, len = colors.length; i < len; i++) {
console.log(colors[i]); // red blue green
}
/*
* 上面是标准的for循环代码,通过变量i来跟踪colors数组的索引,循环每次执行时,如果 i 不大于数组长度
* len 则加1,并执行下一次循环。
* 如果有循环嵌套则需要跟踪多个变量,代码复杂度大大增加。
* 迭代器出现的宗旨就是消除这种复杂性并减少循环中的错误
* */
// 2. 什么是迭代器
/**
* 迭代器是一种特殊的对象, 它具有专门为迭代过程设计的专有接口,所有的迭代器对象都有一个 next()方法
* 每次都调用返回一个结果对象。
* 结果对象有两个属性
* value : 下一个将要返回的值
* done : 布尔类型,当没有更多值时返回 true
*/
// 使用ECMAScript5语法创建迭代器
function createIteratorES5(items) {
var i = 0;
return {
next() {
var done = i >= items.length;
var value = !done ? items[i++] : undefined;
return {
done: done,
value: value
}
}
}
}
var iterator = createIteratorES5([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}
// 3. 什么是生成器
/*
ECMAScript6引入了一个生成器对象,它使得创建迭代器对象的过程变得很简单
* 生成器是一种迭代器函数,通过function关键字后面的(*)来标识。函数中会用到
* 新的关键字 yield
*
* */
// 生成器
function *createIterator() {
// 指定next()方法返回值以及返回顺序
yield 1;
yield 2;
yield 3;
}
iterator = createIterator();
console.log(iterator.next().value); // 1
console.log(iterator.next().value); // 2
console.log(iterator.next().value); // 3
/**
* 生成器函数最有趣的部分就是,每当执行完一条yield语句函数后都会自动停止执行,直到
* 再次调用迭代器的next()方法才会继续调用.
* 使用yield关键字可以返回任何值或者表达式
*/
// 生成器是返回迭代器的函数
function *createItemIterator(items) {
for (var i = 0, len = items.length; i < len; i++) {
// 指定next()方法返回值以及返回顺序
yield items[i];
}
}
let itemIterator = createItemIterator([1,2,3]);
console.log(itemIterator.next().value); // 1
console.log(itemIterator.next().value); // 2
console.log(itemIterator.next().value); // 3
console.log(itemIterator.next().value); // undefined
// NOTE yield使用的限制,只允许在内容访问
/*
function *createDemo(items) {
items.forEach(function (item) {
yield item; // 语法错误
});
}
createDemo([1,2,3]);*/
// 4. 生成器函数表达式
let appleIterator = function *(items) {
for (var i = 0, len = items.length; i < len; i++) {
yield items[i];
}
}
let appItem = appleIterator(["java","JavaScript","Html"]);
console.log(appItem.next().value); // java
console.log(appItem.next().value); // JavaScript
console.log(appItem.next().value); // Html
console.log(appItem.next().value); // undefined
// 5. 生成器对象的方法
let o = {
createItemIterator : function *(items) {
for (var i = 0, len = items.length; i < len; i++) {
yield items[i];
}
}
}
item = o.createItemIterator([10,20,30]);
console.log(item.next().value); // 10
console.log(item.next().value); // 20
console.log(item.next().value); // 30
console.log(item.next().value); // undefined