Arlen Stalwick

Software Developer

Hey there, I'm Arlen Stalwick, VP Engineering @ Wavo.me. I write about my projects and whatever it is that I'm trying to teach myself.


Javascript - Pass by value or pass by reference?

Is Javascript a pass-by-value language, or a pass-by-reference language?

It's an important question, and (in practice) the answer is actually: neither. Actually, technically, the answer is: Javascript is purely pass-by-value. The reason that I say 'neither' is because 'pass-by-value' really does not explain Javascript's variable passing behaviour in any meaningful way. Lets dig into why.

First, just to get them out of the way, primitives (Number, String, etc) are always pass-by-value.

function changeValue(toChange) {  
    toChange = 2;
}

var num = 1;  
console.log(num);  
changeValue(num);  
console.log(num);

// Output:
// 1
// 1

It only gets weird when you get into object passing. Now, technically, Javascript is pass-by-value. But take a look at this code:

function changeValue(toChange) {  
    toChange.value = 2;
}

var obj = {value: 1};  
console.log(obj.value);  
changeValue(obj);  
console.log(obj.value);

// Output:
// 1
// 2

So, ok, clearly it's pass-by-reference, no? If it were pass-by-value, we would be unable to change the value of the passed-in object, we'd be changing a copy of that value inside changeValue().

Well, now that you're convinced Javascript is pass-by-reference, look at this:

function changeValue(toChange) {  
    toChange = {value: 2};
}

var obj = {value: 1};  
console.log(obj.value);  
changeValue(obj);  
console.log(obj.value);

// Output:
// 1
// 1

Whaaat? In this case, we've assigned a new object to toChange. In pass-by-reference, one would expect obj to reflect this change, but it does not. What in the world... ?

So, here's what's happening: Javascript is actually passing a reference to obj by value. (Say that again...?) Javascript is effectively copying the reference, not the referred-to object. When you call changeValue(obj), you're creating two (completely independent) references to the same object. Outside of the function, you have obj, and inside the function, you have toChange. They both refer to the same object in memory, but the reference variables themselves are independent.

That means that if you modify an individual property, you'll be dereferencing the actual object, and you'll be modifying the property directly on the object itself. That's why, in the first example, the outer obj variable reflects the change to the inner toChange variable.

When you assign a new object to toChange, though, you're changing the reference entirely. You're saying 'hey, toChange variable, point at this new object over here, please.' This does not affect obj's reference in any way. obj is still referring to our original object. The upshot of this is: toChange and obj are entirely independent, and modifying toChange will no longer affect obj.

So, what's the answer? Technically (language internals), it's pass-by-value. In practice, I'd put it like this: Javascript is pass-by-reference for objects, with the small exception that assigning a new object will break the reference.

comments powered by Disqus