☕ NEW! 完成新手任務即可參加抽獎!LINE 星巴克禮券等你拿,名額有限!        🎉 推廣活動:邀請好友註冊 DevLearn,累積推薦抽 LINE 星巴克禮券! 活動詳情 →        🔥 活動期間 2026/4/1 - 5/31 |已有 0 人參加       
javascript 中級

迭代器與產生器

迭代器(Iterator)

// 可迭代物件都有 Symbol.iterator 方法
let arr = [10, 20, 30];
let iterator = arr[Symbol.iterator]();

console.log(iterator.next());  // { value: 10, done: false }
console.log(iterator.next());  // { value: 20, done: false }
console.log(iterator.next());  // { value: 30, done: false }
console.log(iterator.next());  // { value: undefined, done: true }

// for...of 背後就是在用迭代器
for (let item of arr) {
    console.log(item);         // 10, 20, 30
}

自訂可迭代物件

let range = {
    from: 1,
    to: 5,

    // 實作 Symbol.iterator
    [Symbol.iterator]() {
        let current = this.from;
        let last = this.to;
        return {
            next() {
                return current <= last
                    ? { value: current++, done: false }
                    : { done: true };
            }
        };
    }
};

for (let num of range) {
    console.log(num);          // 1, 2, 3, 4, 5
}

// 也可以用展開運算子
let nums = [...range];         // [1, 2, 3, 4, 5]

產生器(Generator)

// function* 定義產生器函式
function* numberGenerator() {
    yield 1;                   // ← 暫停,回傳 1
    yield 2;                   // ← 暫停,回傳 2
    yield 3;                   // ← 暫停,回傳 3
}

let gen = numberGenerator();
console.log(gen.next());      // { value: 1, done: false }
console.log(gen.next());      // { value: 2, done: false }
console.log(gen.next());      // { value: 3, done: false }
console.log(gen.next());      // { value: undefined, done: true }

// 可以用 for...of
for (let n of numberGenerator()) {
    console.log(n);            // 1, 2, 3
}

產生器的實用場景

無限序列

function* fibonacci() {
    let a = 0, b = 1;
    while (true) {             // ← 無限迴圈也沒問題!
        yield a;               // ← 每次 next() 才執行到這裡
        [a, b] = [b, a + b];
    }
}

let fib = fibonacci();
console.log(fib.next().value); // 0
console.log(fib.next().value); // 1
console.log(fib.next().value); // 1
console.log(fib.next().value); // 2
console.log(fib.next().value); // 3

// 取前 10 個
function take(gen, n) {
    let result = [];
    for (let i = 0; i < n; i++) {
        result.push(gen.next().value);
    }
    return result;
}
console.log(take(fibonacci(), 10));
// [0, 1, 1, 2, 3, 5, 8, 13, 21, 34]

ID 產生器

function* idGenerator(prefix = "id") {
    let id = 1;
    while (true) {
        yield `${prefix}_${id++}`;
    }
}

let userIds = idGenerator("user");
console.log(userIds.next().value);  // "user_1"
console.log(userIds.next().value);  // "user_2"

async 產生器

// 非同步產生器
async function* fetchPages(url) {
    let page = 1;
    while (true) {
        let response = await fetch(`${url}?page=${page}`);
        let data = await response.json();
        if (data.length === 0) return;    // ← 沒資料就停
        yield data;
        page++;
    }
}

// 使用 for await...of
async function getAllUsers() {
    let allUsers = [];
    for await (let page of fetchPages("/api/users")) {
        allUsers.push(...page);
    }
    return allUsers;
}

💡 大家的想法 · 0

載入中...
💬 即時聊天室 🟢 0 人在線
😀 😎 🤓 💻 🎮 🎸 🔥
➕ 新問題
📋 我的工單
💬 LINE 社群
🔒
需要註冊才能使用此功能
註冊帳號即可解鎖測驗、遊戲、簽到、筆記下載等所有功能,完全免費!
免費註冊