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

JavaScript链表构建中head引用变化及指向尾节点的原理问询

链表代码执行过程解析

先看目标代码:

let head = { val: 0, next: null };

let list = head;

const arr = [1, 2, 3, 4];

for (let c of arr) {
  list.next = { val: c, next: null };
  list = list.next;
}

console.log(head);

问题与解答

1. 整个过程的具体执行步骤是怎样的?

  • 初始阶段:创建初始对象{ val: 0, next: null },变量head和list的栈内存中都存储该对象的引用地址,二者指向同一个对象。
  • 循环遍历数组(共4次):
    • 第一次循环(c=1):
      1. 给当前list指向的对象的next属性赋值新对象{ val: 1, next: null },此时初始对象变为{ val: 0, next: { val: 1, next: null } },head因指向初始对象,自然能访问到更新后的结构。
      2. 将list重新赋值为list.next,也就是刚创建的{ val: 1, next: null },此时list的引用切换到这个新节点,head仍指向初始头节点。
    • 第二次循环(c=2):
      1. 给当前list指向的{ val: 1, next: null }的next属性赋值{ val: 2, next: null },链表结构延伸为{ val: 0, next: { val: 1, next: { val: 2, next: null } } }。
      2. list更新为这个新的{ val: 2, next: null }节点。
    • 第三次循环(c=3):
      1. 给list指向的{ val: 2, next: null }的next赋值{ val: 3, next: null },链表继续扩展。
      2. list切换到这个新节点。
    • 第四次循环(c=4):
      1. 给list指向的{ val: 3, next: null }的next赋值{ val: 4, next: null },最终链表完整结构为:
        { val: 0, next: { val: 1, next: { val: 2, next: { val: 3, next: { val: 4, next: null } } } } }
        
      2. list切换到这个尾节点{ val: 4, next: null }。
  • 最终输出:执行console.log(head),输出的是初始头节点对象,通过它的next属性可以遍历整个链表。

2. 执行过程中是否存在引用变化?

  • head的引用全程不变:它始终指向最初创建的{ val: 0, next: null }对象,只是该对象的next属性被不断修改,指向新的子节点。
  • list的引用每次循环都会改变:初始和head指向同一对象,每次循环后半段都会把list的引用更新为刚创建的新节点,直到最后指向链表的尾节点。

3. 为何head变量最终指向的是尾节点?

这是一个误解:head自始至终都指向链表的头节点(即最初的{ val: 0, next: null })。你看到console.log(head)输出包含整个链表,是因为头节点的next属性链接着所有后续节点,并非head指向了尾节点。真正指向尾节点的是list,因为每次循环都将它移动到下一个新节点。


内容的提问来源于stack exchange,提问作者Nazmul Islam Nahid

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.30 15:46:21