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

为何引用同一dummy对象的fast/slow指针修改slow不影响fast?

JavaScript对象引用与变量赋值的本质——以快慢指针为例

在下面这段删除链表倒数第N个节点的JavaScript代码中,slow和fast初始都指向同一个dummy对象,但执行slow = slow.next后,fast完全没受影响。为什么会出现这种情况?

function ListNode(val, next) {
  this.val = (val === undefined ? 0 : val)
  this.next = (next === undefined ? null : next)
}

var removeNthFromEnd = function(head, n) {
  let dummy = new ListNode(0);
  dummy.next = head;

  let slow = dummy;
  let fast = dummy;
  slow = slow.next
  console.log(fast)

  for (let i = 0; i <= n; i++) {
    fast = fast.next;
  }

  while (fast !== null) {
    slow = slow.next;
    fast = fast.next;
  }

  return dummy.next;
};

removeNthFromEnd({
  val: 1,
  next: {
    val: 2,
    next: {
      val: 3,
      next: {
        val: 4,
        next: {
          val: 5,
          next: null
        }
      }
    }
  }
}, 2)

核心原因:变量存的是对象引用地址,而非对象本身

JavaScript里的对象存储在堆内存中,变量只是保存了指向该对象的内存地址。这里的变量重新赋值和对象属性修改是完全不同的操作:

  • 初始阶段:let slow = dummy; let fast = dummy;
    此时slow和fast两个变量保存的是同一个内存地址,指向堆里的dummy对象。如果这时候修改对象的属性(比如slow.next = new ListNode(6)),因为指向同一个对象,fast.next也会看到这个变化。

  • 执行slow = slow.next时:
    这是给slow变量重新赋值——把slow里的地址替换成slow.next指向的节点的内存地址。而fast变量里保存的还是原来dummy对象的地址,自然不会受到影响。

简单对比示例

let obj1 = {a: 1};
let obj2 = obj1;

// 修改对象属性:两个变量指向同一对象,都会变化
obj1.a = 2;
console.log(obj2.a); // 输出 2

// 重新赋值变量:obj2指向原对象,不受影响
obj1 = {b: 3};
console.log(obj2); // 输出 {a: 2}

回到链表代码,slow = slow.next就是典型的变量重新赋值操作,只是改变了slow的指向地址,并没有修改原dummy对象的内容,所以fast的指向完全不会跟着改变。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.22 01:15:09