使用工厂函数实现JavaScript链表:head/tail/length未更新问题
链表工厂函数内部状态无法外部访问问题
你用工厂函数实现链表时,遇到了这样的问题:调用prepend、append后返回的状态是正确的,但外部直接访问l.head却返回null,内部的head、tail和length变量修改后无法被外部获取。
原代码
const Node = (data = null, next = null) => { return {data, next} } const LinkedList = () => { let head = null; let tail = null; let length = 0; // append(value) adds a new node containing value to the end of the list const append = (value) => { const newTailNode = Node(value); if(!head){ return prepend(value) }else{ let current = head; while(current.next){ current = current.next; } current.next = newTailNode; tail = newTailNode; length++; return tail } } // prepend(value) adds a new node containing value to the start of the list const prepend = (value) => { head = Node(value, head) length++; return {head, length} } // size returns the total number of nodes in the list const size = () => { return length } return {prepend, append, size,} }; const l = LinkedList() l.prepend(55) l.prepend(44) l.prepend(33) l.append(66) l.append(77) console.log(l.head)
问题原因
- 内部变量未暴露:
head、tail是LinkedList函数内部的闭包变量,你返回的对象里只包含prepend、append、size方法,没有提供访问这些内部变量的途径,所以外部直接l.head自然拿不到值。 - prepend未正确更新tail:当链表为空时执行prepend,tail应该和head指向同一个节点,但原代码里tail始终为null,后续append虽然能正确添加节点,但tail变量的状态是错误的。
修正方案
我们需要在返回的对象里添加访问内部状态的方法,同时修复prepend里的tail更新逻辑:
const Node = (data = null, next = null) => { return {data, next} } const LinkedList = () => { let head = null; let tail = null; let length = 0; const append = (value) => { const newTailNode = Node(value); if(!head){ return prepend(value) }else{ tail.next = newTailNode; // 直接用tail,不用遍历,效率更高 tail = newTailNode; length++; return tail } } const prepend = (value) => { head = Node(value, head); // 链表为空时,tail也指向新节点 if (!tail) { tail = head; } length++; return {head, length} } const size = () => { return length; } // 添加获取内部状态的方法 const getHead = () => { return head; } const getTail = () => { return tail; } return {prepend, append, size, getHead, getTail}; }; const l = LinkedList() l.prepend(55) l.prepend(44) l.prepend(33) l.append(66) l.append(77) console.log(l.getHead()) // 输出 {data: 33, next: {data: 44, next: {...}}} console.log(l.getTail()) // 输出 {data: 77, next: null} console.log(l.size()) // 输出 5
额外优化点
- append方法里不用再遍历整个链表找最后一个节点,直接用tail变量就能定位,提升了效率。
- 新增
getHead、getTail方法,安全地暴露内部状态,避免直接修改内部变量。
内容的提问来源于stack exchange,提问作者Farzam
相关产品推荐
相关产品推荐

