P.Brian.Mackey
P.Brian.Mackey

Reputation: 44285

When are values copied?

I know Javascript always passes objects by reference. But what about the other types?

number - ?
string - Immuteable, so it shouldn't matter
object - ref
array - ?
function - ?
regexp - ?

I came to the conclusion that not all values in Javascript can be objects nor can they be pass by reference with the following code:

function SomeFunc(func) {
    var numba = 0;
    var innerFunc = function() {
       numba = func(numba);//try commenting me out and switching to next line
        //func(numba);//numba fails to increment
       return numba;
    };
   return innerFunc;
}

//this variable should persist the numba variable through closure.  Incrementing each call by 1.
var closure = SomeFunc(function(numba) {
    numba = numba + 1;
    return numba;
});

document.writeln(closure());
document.writeln(closure());
document.writeln(closure());

Because numba fails to increment, unless I return the number and updated the variable in closure...then that tells me this is not pass by reference. Am I missing something?


or take the very basic

function UpdateNumber(numba) {
    numba = 10;  
   document.writeln('in func number becomes ' + numba);
}

var numba2 = 5;
UpdateNumber(numba2);

document.writeln('back to caller number is ' + numba2);
//in func number becomes 10 
//back to caller number is 5 

Upvotes: 1

Views: 198

Answers (3)

marcus
marcus

Reputation: 5199

I think it is more productive to think about like this:

  • There are mutable (objects, arrays, etc.) and immutable (numbers, booleans, strings) values.
  • Parameter passing is always by assignment.
  • Assignment to parameters can't be seen outside the function, since you are just changing a local variable to point somewhere else.
  • If the object is mutable and you call methods or assign to properties, those changes are seen outside the function (i.e., no copy has been made to the object when it was passed into the function)

So you don't need to learn if a type is passed by reference, you need to check if it is mutable.

Upvotes: 2

xavierm02
xavierm02

Reputation: 8787

Every object is passed by reference. And in fact, everything is an object.

function addProperty( o ) {
    o.property = 'value';
}

// here, we can see that even numbers are passed by reference
var n = new Number( 1 );
addProperty( n );
console.log( n.property );// 'value'

But even though everything is passed by reference, for litterals, you can consider that they are passed by value because you can not modify them.

var n = 1;
n.property = 'value';
console.log( n.property );// undefined

In ES 5, there is this new function Object.freeze that makes an object impossible to modify. Basically, what you're doing when passing a litteral, is passing an immutable object.

var n = 1;
var o = Object.create( null );
Object.freeze( o );
doWhatTheFuckYouWant( o );
doWhatTheFuckYouWant( n );

In both cases, you can be sure that the function won't change anything to your object because there is nothing that can be changed about the object. Therefore, you just don't care whether it is cloned or not.

Upvotes: 1

JaredPar
JaredPar

Reputation: 755179

No. JavaScript always passes by value, not by reference.

People often confuse the ability to modify an object in a method and have the modification be visible on the outside as being pass by reference. This is not the case. Pass by reference means modifying what the value points to is visible outside the function. For example

var f1 = function (p1) {
  p1 = 42;
};
var x = {};
f1(x);

In this example if JavaScript implemented pass by reference then x === 42 would be true. However it's not. The variable x would still have the value {}

Upvotes: 4

Related Questions