Javascript 为什么this.tail会更改Linkedlist类中this.head的属性?
考虑一个模仿LinkedList数据结构的LinkedList类,如下所示:Javascript 为什么this.tail会更改Linkedlist类中this.head的属性?,javascript,class,oop,linked-list,this,Javascript,Class,Oop,Linked List,This,考虑一个模仿LinkedList数据结构的LinkedList类,如下所示: 类链接列表{ 构造函数(值){ 这个头={ 价值:价值, 下一个:空 }; this.tail=this.head; 这个长度=1; } 附加(值){ 常数newNode={ 价值:价值, 下一个:空 } this.tail.next=newNode;//为什么会更改head.next? this.tail=newNode; 这个.length++; 归还这个; } } 让myLinkedList=newLinkedL
类链接列表{
构造函数(值){
这个头={
价值:价值,
下一个:空
};
this.tail=this.head;
这个长度=1;
}
附加(值){
常数newNode={
价值:价值,
下一个:空
}
this.tail.next=newNode;//为什么会更改head.next?
this.tail=newNode;
这个.length++;
归还这个;
}
}
让myLinkedList=newLinkedList(10);
myLinkedList.append(5);
日志输出
LinkedList{
head:{value:10,next:{value:5,next:null},
尾部:{value:5,next:null},
长度:2
}
我看到this.tail.next
也将更改tail的next属性(然后this.tail=newNode
将tail重新分配给newNode)。我不明白的是为什么this.tail.next
还会更改this.head的next属性
此外,当将另一个数字追加到列表myLinkedList.append(16)
时,它会不断更新head的下一个属性,如下所示:
LinkedList{
head:{value:10,next:{value:5,next:[Object]},
尾部:{value:16,next:null},
长度:3
}
也许一个可能的原因与我定义的构造函数有关,在这里我定义了this.tail=this.head
?但我不是很确定,因为这一个只分配头到尾的值
总之,我的问题是为什么
this.tail.next=newNode
会更改头部的next属性?另外,当附加另一个值时,为什么会更改head.next.next等等?当构造函数运行时,this.tail
和this.head
引用同一个对象,因此对this.tail.next
的任何赋值都可以在this.head
中看到,因为这实际上是对正在变异的同一个对象的引用
这可能有助于形象化这一点。一旦构造函数运行,就会出现这种情况:
this.head
↓
┌───────────┐
│ value: 10 │
│ next: null│
└───────────┘
↑
this.tail
然后,append(5)
将首先创建一个新节点:
this.head newNode
↓ ↓
┌───────────┐ ┌───────────┐
│ value: 10 │ │ value: 5 │
│ next:null │ │ next:null │
└───────────┘ └───────────┘
↑
this.tail
然后this.tail.next=newNode执行code>,这是对第一个对象中的next
属性的修改:
this.head newNode
↓ ↓
┌───────────┐ ┌───────────┐
│ value: 10 │ │ value: 5 │
│ next: ———————→ │ next:null │
└───────────┘ └───────────┘
↑
this.tail
所以实际上,这也改变了this.head.next
。。。因为它是完全相同的属性
然后this.tail=newNode代码>被执行:
this.head newNode
↓ ↓
┌───────────┐ ┌───────────┐
│ value: 10 │ │ value: 5 │
│ next: ———————→ │ next:null │
└───────────┘ └───────────┘
↑
this.tail
下次调用append
时,将更新第二个对象的next
属性,因此我们得到:
this.head newNode
↓ ↓
┌───────────┐ ┌───────────┐ ┌───────────┐
│ value: 10 │ │ value: 5 │ │ value: 16 │
│ next: ———————→ │ next: ———————→ │ next:null │
└───────────┘ └───────────┘ └───────────┘
↑
this.tail
是的,这一变化也可以追溯到this.head,因为。。。这是一个链接列表。。。所以它应该是可追踪的。由于每个next
属性都指向下一个节点,您可以找到从head
到任何节点的路径。“可能有一个可能的原因与我定义this.tail=this.head
的构造函数有关。”-是的,当然这就是原因:两个属性现在都拥有相同的对象引用,然后您将更改从两个位置引用的对象的。next
属性。第一个附加将更新head(因为开头的head是tail)。第二个附加没有更新头
,它只是控制台.log
以这种方式表示它。也就是说,你的代码很好。(你的代码唯一奇怪的地方是链表总是至少包含一个元素,不能为空)这不是我的代码(是的,它应该是这样工作的,但我不明白它是如何工作的,所以我问:D(经过一些思考tbh)),所以实际上它只是对象引用。头部的参照对象指定给尾部。当我执行tail.next
时,它还会更新它引用的对象,即head.next。是吗?谢谢你简单易懂的说明!我真的很感激!