You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用JavaScript的Symbol.iterator实现单链表可迭代,解决遍历返回undefined问题

问题根因

你注释的Symbol.iterator实现不符合JS标准迭代器协议要求:迭代器的next()方法返回的对象中,存储当前迭代值的属性名必须是value,你写的是data,所以for...of循环无法读取到正确的节点值,才会返回undefined。

修复后的完整代码

// 自定义节点类
class Node {
    constructor(data) {
        this.data = data;
        this.next = null
    }
}

class LinkedList {
    constructor(){
        this.head = null;
        this.size = 0;
    }
    add(data){
        let node = new Node(data);
        let current;
        if(this.head === null){
            this.head = node;
        } else{
            current = this.head;
            while(current.next) {
                current = current.next;
            }   
            current.next = node;
        }
        this.size++
    }

    [Symbol.iterator]() {
        let current = this.head;
        return {
            next: () => {
                if (!current) return { done: true };
                const { data, next } = current;
                current = next;
                // 把原来的data属性名改成value即可
                return { value: data, done: false };
            },
        };
    }

    log(){
        let current = this.head;
        let str = "";
        while (current) {
            str += current.data + ", ";
            current = current.next;
        }
        if (str !== "") {
            console.log(str);
        } else{
            console.log("List Is Empty");
        }
    }
}

// 测试代码:先初始化链表实例并添加测试数据
const ll = new LinkedList();
ll.add(5);
ll.add(10);
ll.add(10);
let sum = 0;
for(const n of ll) {
    console.log(n);
    sum += n;
}

console.log(sum);
// 输出25

ll.log();

补充说明

你原测试代码中没有初始化ll实例、也没有提前添加节点数据,实际运行时需要先完成这两步再遍历求和。迭代器协议规定只要done属性不为true,就会读取value属性作为当前迭代项的值,只要遵循这个约定,所有可迭代语法(for...of、展开运算符...、Array.from等)都可以直接用在你的链表实例上。

内容的提问来源于stack exchange,提问作者techdan

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.07 12:57:01