JavaScript带this.tail的LinkedList push方法值引用疑问
JavaScript引用与单链表push方法的疑问解答
一、单链表push方法的引用逻辑疑问
原实现代码
class Node { constructor(val) { this.val = val; this.next = null; } } class SLL { constructor() { this.head = null; this.tail = null; this.length = 0; } push(val) { let newNode = new Node(val) if (!this.head) { this.head = newNode; this.tail = this.head; } else { console.log(this.tail); console.log(this.tail.next); debugger this.tail.next = newNode; this.tail = newNode; } this.length++; } } let x = new SLL(); x.push('Hi'); x.push('Hello'); x.push('How'); x.push('Are'); x.push('You'); x.push('Man');
疑问解答
你感觉第三次push('How')时this.tail和this.head还有关联,本质是链表节点之间的引用链在起作用,不是tail直接引用head:
- 第一次
push('Hi'):head和tail都指向同一个Node实例(值为'Hi'),此时两者指向同一块内存。 - 第二次
push('Hello'):进入else分支,先把this.tail.next(也就是'Hi'节点的next属性)指向新创建的'Hello'节点,然后把this.tail的引用改成指向'Hello'节点。此时head还是指向'Hi'节点,而'Hi'节点的next指向'Hello'节点,所以整个链表是head -> 'Hi' -> 'Hello' <- tail,tail和head通过节点的next属性形成了间接关联,并不是tail直接引用head。 - 第三次
push('How'):此时this.tail指向'Hello'节点,修改它的next指向'How'节点,再把tail改成指向'How'节点。这时候head依然指向'Hi','Hi'→'Hello'→'How',整个链表的引用链是完整的,你感知到的“关联”就是这个链式结构导致的。
二、对象赋值与引用断开的疑问
原测试代码
let l = { a : 1} let o; let p; o = l; p = o; p.a = 2; console.log("l",l); console.log("o",o); console.log("p",p); p = { a:10}; console.log("l",l); console.log("o",o); console.log("p",p);
疑问解答
- 执行
p = { a:10 }时,会创建新的内存空间,因为对象字面量{a:10}是一个全新的对象,JavaScript会为它分配独立的内存地址。 - 此时
p和o之间的引用会完全断开:之前o和p都指向l对应的那个{a:1}(后来被改成{a:2})的对象;当p被赋值为新对象后,p的引用指向新内存地址,而o仍然指向原来的旧对象,两者再无关联。
内容的提问来源于stack exchange,提问作者Srujan R
相关产品推荐
相关产品推荐

