1

My LinkedList Class has two properties

  1. this.head
  2. this.size

this.head is used to contain the list of objects. Simple logic says, if I update this.head , its value should be updated. If I, however, assign its value to some other variable and then try to update that variable, then the original this.head shouldn't update.

Eg:

printElements(){
    let current = this.head;
    while(current){
      console.log(current.data)
      current = current.next;
    }
  };

But this piece of code contradicts that situation. I don't know why this.head is getting updated here when it's not directly referenced.

insertAt(data, index){

    if(index > 0 && index > this.size)
      return 
    
    const node = new Node(data);
    let current, previous;

    current = this.head;
    let count = 0;

    while(count < index){
      previous = current;
      count++;
      current = current.next;
    }

    node.next = current;
    previous.next = node;

  };

The entire piece of code

class Node{
  constructor(data, next = null){
    this.data = data;
    this.next = next;
  }
}

class LinkedList{
  constructor(){
    this.head = null;
    this.size = 0;
  };
    
  insert(data){
    this.head = new Node(data, this.head);
    this.size++;
  };

  insertAt(data, index){

    if(index > 0 && index > this.size)
      return    

    const node = new Node(data);
    let current, previous;

    current = this.head;
    let count = 0;

    while(count < index){
      previous = current;
      count++;
      current = current.next;
    }

    node.next = current;
    previous.next = node;

  };

  printElements(){
    let current = this.head;
    while(current){
      console.log(current.data)
      current = current.next;
    }
  };

}
jsdsalgo
  • 15
  • 4
  • Elaborate, please, on what you think the problem is. Specifically, which lines, what they're doing and what you think they should be doing instead. – Welbog Feb 14 '21 at 16:16
  • in the insertAt function, when we update `node.next` and `previous.next`, it is directly affecting `this.head` without explicitly updating `this.head`. This behaviour is not consistent when it comes to printElements() function. – jsdsalgo Feb 14 '21 at 16:22
  • Have you tried stepping through the code with a debugger to see what happens? Why do you think updating the head's `next` pointer is a problem? How else would you insert a node immediately after the head? – Welbog Feb 14 '21 at 16:25
  • no, that is exactly how you would insert a node by updating the next pointer. What i'm confused as to how javascript updates the properties because it doesn't do so in the printElements when we are printing the list. – jsdsalgo Feb 14 '21 at 16:35
  • 1
    I'm really struggling to understand the question you're asking. Are you wondering how, when `previous = head` and we say `previous.next = node`, how `head` is updated? – Welbog Feb 14 '21 at 16:41
  • Please post a [mcve] with code that we can execute that doesn't contain `....` and actually instantiated a list and calls the method – Bergi Feb 14 '21 at 16:46
  • @Welbog yes, or you could say why current = current.next doesn't update this.head when we invoke the printElements function. – jsdsalgo Feb 14 '21 at 16:50
  • @Bergi post updated. – jsdsalgo Feb 14 '21 at 16:50
  • `current = current.next` only updates the *variable* `current`, not a property of any object. – Bergi Feb 14 '21 at 16:56
  • OK, the thing you're missing is an understanding that variables and objects aren't the same thing. There are lots of resources for this, such as https://stackoverflow.com/questions/9224517/what-are-classes-references-and-objects. But basically, a variable references an object. It's like an arrow pointing to a thing. You can change where the arrow points without changing the thing, and you can change the thing regardless of which arrows are pointing to it. – Welbog Feb 14 '21 at 16:56
  • @jsdsalgo Thank you for the update, but that still doesn't show how you're calling the method. Btw, `insertAt("somevalue", 0)` doesn't work. – Bergi Feb 14 '21 at 16:57

1 Answers1

1

Let's take a stab at minimal examples that show the behaviour you're asking about, keeping it mostly language agnostic, as this is not specific to JS.


Why doesn't this snippet print 20? It prints 10 instead.

b = new Node(20);
a = new Node(10, b);
c = a;
c = c.next;
console.log(a.data);

Why doesn't this snippet print 10? It prints 20 instead.

b = new Node(10);
a = b;
a.data = 20;
console.log(b.data);

Both of these questions arise from conflating variables and objects with each other. The two concepts are related but distinct.

When we say something like b = new Node(20);, we're declaring a variable b, instantiating an object Node(20), and referencing the object from the variable. b holds a reference to Node(20). If we say b.data = 30;, now b holds a reference to Node(30). This was the same Node as before, but its data has changed. So far, the object/variable distinction hasn't revealed itself.

We could also say a = b;, as in the second example. This means we have two variables both referencing the same Node(20) object. If we say a.data = 30;, then the object referenced by variable a's data is set to 30. So since there's only one Node object, b.data and a.data are both 30.

When we say something like c = a; c = c.next;, the Node referenced by a is still there, still referenced by a. a is like an arrow, pointing at Node(10). c is another arrow, also pointing at Node(10). c = c.next; has no impact on a. It's just changing what c is pointing to.

Welbog
  • 59,154
  • 9
  • 110
  • 123