生成器与迭代器 
题目1: 生成器函数的语法是什么?如何使用 yield? 
答案: 生成器函数使用 function* 语法定义,使用 yield 关键字产生值:
javascript
function* numberGenerator() {
    yield 1;
    yield 2;
    yield 3;
}
const gen = numberGenerator();
console.log(gen.next().value); // 1
console.log(gen.next().value); // 2
console.log(gen.next().value); // 3扩展: yield 可以接收值,这个值会作为上一次 next() 调用的返回值。
题目2: 什么是迭代器?如何手动实现一个迭代器? 
答案: 迭代器是一个对象,它定义了一个 next() 方法,该方法返回一个包含 value 和 done 属性的对象。
手动实现迭代器:
javascript
function createIterator(array) {
    let index = 0;
    return {
        next: function() {
            if (index < array.length) {
                return { value: array[index++], done: false };
            } else {
                return { done: true };
            }
        }
    };
}
const it = createIterator([1, 2, 3]);
console.log(it.next()); // { value: 1, done: false }
console.log(it.next()); // { value: 2, done: false }
console.log(it.next()); // { value: 3, done: false }
console.log(it.next()); // { done: true }扩展: ES6 引入了 Symbol.iterator,允许对象定义它们的迭代行为。
题目3: 如何使用生成器函数实现异步操作? 
答案: 生成器函数可以用于实现异步操作,通常与 Promise 结合使用:
javascript
function* asyncGenerator() {
    const result1 = yield fetch('https://api.example.com/data1');
    console.log(result1);
    const result2 = yield fetch('https://api.example.com/data2');
    console.log(result2);
}
function run(generator) {
    const iterator = generator();
    function iterate(iteration) {
        if (iteration.done) return Promise.resolve(iteration.value);
        return Promise.resolve(iteration.value)
            .then(x => iterate(iterator.next(x)));
    }
    return iterate(iterator.next());
}
run(asyncGenerator);扩展: 这种模式是 async/await 的前身,现在通常直接使用 async/await。
题目4: 什么是可迭代对象?如何创建一个可迭代对象? 
答案: 可迭代对象是实现了 Symbol.iterator 方法的对象。创建可迭代对象:
javascript
const iterableObject = {
    [Symbol.iterator]: function* () {
        yield 1;
        yield 2;
        yield 3;
    }
};
for (const item of iterableObject) {
    console.log(item); // 1, 2, 3
}扩展: 数组、字符串、Map 和 Set 都是内置的可迭代对象。
题目5: 生成器函数和普通函数的区别是什么? 
答案: 主要区别:
- 语法:生成器函数使用 function*声明
- 执行:生成器函数返回一个生成器对象,而不是直接执行函数体
- 暂停和恢复:生成器函数可以使用 yield暂停执行,并在之后恢复
- 状态保持:生成器函数可以在多次调用之间保持其内部状态
- 双向通信:可以通过 next()方法向生成器传值,通过yield从生成器获取值
扩展: 生成器函数特别适合于处理大量数据或无限序列,因为它们可以按需生成值,而不需要一次性将所有值存储在内存中。