如何用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
相关产品推荐
相关产品推荐

