bittersweetryan
bittersweetryan

Reputation: 3443

How are primitives passed into functions as arguments in JavaScript?

When passing a primitive into a JavaScript function as an argument is a copy of the value being ( i.e. a new variable being created ) passed into the function or is it just a pointer to the variables location in memory like what happens with objects? Since objects are mutable its easy to prove, however, since primitives are immutable they will always be reassigned so it's hard to tell whats is happening behind the scenes.

In the following code ( http://jsbin.com/egufog/2/edit ) demonstrates what I mean:

var pvalue = 'foo'; //primitive

var ovalue = { foo : 'foo' }; //object

changeMe( pvalue, ovalue ); //changes values

console.log( pvalue, ovalue ); //pvalue unchanged, ovalue was changed

reassignMe( ovalue ); //reassigns the object, breaking the reference

console.log( ovalue ); //ovalue remains unchanged

function changeMe( primitive, obj ){
  primitive = 'bar'; //did this reassign the pointer or just create another variable?

  obj.foo = 'bar'; //updates the object in memory
}

function reassignMe( obj ) {
  obj = { baz : 'baz' }; //reassignment breaks the pointer reference
}

Upvotes: 4

Views: 585

Answers (3)

Bergi
Bergi

Reputation: 664579

When passing a primitive into a JavaScript function as an argument is a copy of the value being ( i.e. a new variable being created ) passed into the function or is it just a pointer to the variables location in memory like what happens with objects?

A function parameter always creates a new variable, i.e. a slot with a name that contains a value. As javascript has no pointers, it holds the location of the value not of the variable.

Since primitives are immutable they will always be reassigned so it's hard to tell whats is happening behind the scenes.

Exactly, we don't know. But since they are immutable it does not make a difference whether the variable is assigned a copy of the value itself or the location of the value. The JS engine is free to choose that - I would expect the usage of references for large strings, but not for numbers or boolean values.

changeMe( 'foo' )
function changeMe( primitive, obj ){
    primitive = 'bar'; //did this reassign the pointer or just create another variable?
}

There's no new variable, primitive existed since you called the function. It previously held the value 'foo' (or a pointer to it), and now does hold the value 'bar' (or a pointer to it).

Only for objects we know that the variables holding them contain pointers to the data structure in memory - they are known as "reference values" (in contrast to the primitive ones). If you mutate the data, you can see that from every variable referencing the object.

Upvotes: 3

Pete D
Pete D

Reputation: 837

From what I know when primitive types are passed in an argument of a function then they are passed by value and a copy of the primitive value is passed in the function. Which means that if within the function you change the value of the argument then the 'original' value of the variable is intact.

var pvalue = 'foo'; //primitive

function changeMe(prim) {
    prim = 'bar';
}
changeMe(pvalue);
console.log(pvalue); // pvalue remains foo (unchanged)

However if you try the same with an object it will change the 'original' object since it's new variable in the function will point also to the original object. But that doesn't mean that it was passed in by reference. Check this out.

function changeMe(obj) {
    obj.foo = "foo";
    obj = new Object();
    obj.foo = "bar";
}

var ovalue = { foo : null };
changeMe(ovalue);

alert(ovalue.foo); // Changed to foo but not to bar

This means that if the obj was passed in by refence then when I assigned the new Object to the obj and then changed the property that it would also change the original object's foo property to bar.

So how I think about it is that the object is passed in also by value and when you use that value to assign a property for example it will point it to the same object as before. However if you reassign within the function the obj to a new Object then this new Object will point to a different local Object that can be accessed just within the scope of the function it was created in.

Upvotes: 0

MStodd
MStodd

Reputation: 4746

I think it's too simple to say

console.log( pvalue, ovalue ); //pvalue unchanged, ovalue was changed

If we think of of pvalue and ovalue as references to objects, we save our references on the stack, make copies for the called function to use, then call the function. At this point, the called function has it's own references, but it's still pointing to the same objects, and is therefore able to change them

If we reassign a reference passed into a function, such as

primitive = 'bar'; //did this reassign the pointer or just create another variable?
or
obj = { baz : 'baz' }; //reassignment breaks the pointer reference

Then all we did was change the copy of the original reference, the scope of which is limited to the called function. One we get back to the calling function, we take the original reference off the stack

Upvotes: 1

Related Questions