0

I'm noticing behavior I don't understand in JavaScript. I understand that with regards to primitive types when passed to a function, they're passed by value. If we pass an object, they're passed by reference. What I wanted to do was shorten my code by encapsulating a repetitive section into a function; this function was to take a node object pointing to a node in a linked list, do something with its value, and then move it to the next node in the list. However that's not what happens. I've made a simple example here:

var testObj = {};
testObj.val = 5;
testObj.next = {
    val: 7,
    next: null
} 

var temp = testObj;
console.log("Val before: ", temp.val); //prints 5 

function test(node) {
    console.log(node.val); //prints 5
    node = node.next;
    console.log(node.val); //prints 7
}

test(temp);
console.log("Val after: ", temp.val); //prints 5?? 

First I create a test node with a value and a next field pointing to the next node in the list which also has a value. I create another node which points to the first node in the list (this is common when you want to iterate through the list, you don't want to lose track of the root node.)

I'm confused as to why you can do something like

function test(node) { 
    node.val = 100;
}
console.log(temp.val); //prints 100

And the change in value stays; but if I make the node point to the next item in the list, that change doesn't stay.

Vee
  • 729
  • 10
  • 27
  • Is expected result to change value of `testObj.val` to `testObj.next.val` ? – guest271314 Jan 21 '16 at 15:22
  • http://stackoverflow.com/questions/6605640/javascript-by-reference-vs-by-value?lq=1 – Murat Ozgul Jan 21 '16 at 15:29
  • @MuratOzgul based on my reading of that, it seems impossible to move the node forward down the list because when I pass ```temp``` to ```test(node)```, ```node``` becomes a copy of ```temp``` and any changes I make to it directly only change it itself, not the temp variable in the calling context. But I can for instance change ```node.val``` and the resulting behavior is that the change is carried over to ```temp.val``` – Vee Jan 21 '16 at 17:00

1 Answers1

1

Javascript copies the value to the function you're passing it as an argument to.

var temp = testObj; // temp is defined in this scope
console.log("Val before: ", temp.val); //prints 5 

    function test(node) { //node is defined in those scope, and is not a reference.

        console.log(node.val); //prints node
        node = node.next;
        //if you wouldve done node.value = 10, it wouldve changed for temp as value is encapsulated
        console.log(node.val); //prints node
    }

test(temp); //temp is still the same as it was defined as you didn't change it
console.log("Val after: ", temp.val); //prints temp

If you want to make the argument a reference to the object you're passing, you need to encapsulate it in another object, i.e. if you set the argument again within the function, the reference to the old object disappears. Check out this question

Community
  • 1
  • 1
Glubus
  • 2,819
  • 1
  • 12
  • 26
  • I'm not sure I understand what you're saying... when you say ```If you want to make the argument a reference to the object you're passing, you need to encapsulate it in another object``` I interpreted that like this: http://pastebin.com/bfWGe3aw – Vee Jan 21 '16 at 16:44
  • It is still the same value because you're requesting temp still. If you print container.obj.value once, then after running the function print container.obj.value again, you'll notice they are not the same. Meaning that you can pass objects as values as arguments, and set their properties to different values. You cant change the 'pointer' to temp. – Glubus Jan 22 '16 at 14:35