DEV Community

Cover image for JavaScript: Passing by Value vs Pass by Reference
Dani Schuhman
Dani Schuhman

Posted on

JavaScript: Passing by Value vs Pass by Reference

Photo by Erol Ahmed on Unsplash

What's the big difference between passing Arguments by Reference vs Passing Arguments by Value?

Primitive Values

In JavaScript, as with many other languages, at some point, you'll come across this concept. Going back to the call stack and the heap, and where data is stored, Primitives (Number, String, Boolean, Undefined, Null, Symbol, BigInt) are stored in the call stack. Objects (Object Literal, Arrays, Functions, more...), are stored in the heap.

When we create a primitive value, JavaScript creates a unique identifier with the value name. It then allocates the memory to an address, with a value. The identifier points to the address, but not the value itself. Primitive values, are immutable. Meaning, even if we might reassign a value, or alter it somewhere else, it does not change everywhere else that the value exists.

let season = "Fall";
let nextSeason = season;
season = "Winter";
console.log(season);
console.log(nextSeason);
//// Returns
// Winter 
// Fall
Enter fullscreen mode Exit fullscreen mode

Even though season was reassigned to a value of Winter, when we mutate it, it does not change the fact that nextSeason was initially set to Fall. It remains unchanged.

Reference Values

When we create a new object, it's stored in the heap, as the memory address, and then the value itself. When we declare a variable as an object, the identifier created for it, points to a piece of memory in the stack, which in turn points to a piece of memory in the heap where the object is stored.

Because of this, if multiple copies are created of an object, every time that happens, a new object is not created in memory. It just points to the same identifier for the original object. And so mutating one object has the effect that it changes all objects that point to that same memory address.

const dog = {
    name: "Beau",
    age: 15
};
const puppy = dog; 
puppy.age = "10 months";

console.log('Puppy:', puppy)
// Returns
// Puppy: {name: 'Beau', age: '10 months'}

console.log('Dog:', dog)
// Returns 
// Dog: {name: 'Beau', age: '10 months'}
Enter fullscreen mode Exit fullscreen mode

It's important to understand the difference between Primitives vs Objects, because otherwise it can lead to some pretty nasty surprises, and bugs in our code. Also, so that when moving into functions, it's possible to understand the difference between Passing by Reference vs. Passing by Value.

Passing By Value

Moving into Functions, if we pass a primitive value into a function as an argument, even if a function manipulates that value inside of the context of the function, outside of the function itself, the value will remain as it was.

Ex:

let x = 1;
function alter(arg) {
    arg = 100;
    return arg;
};

change(x)
// Returns 100 
console.log(x)
// returns 1
Enter fullscreen mode Exit fullscreen mode

Passing by Reference

When we pass a reference type to the function, what's copied is the reference object to the memory heap. Both point to the same object in memory. When an object is manipulated in a function, it's the same as manipulating the object itself, as both references point to the same object. Change in one place, and everywhere else, the object has been altered.

const dog = {
    name: "Beau",
    age: 15
};

const happyBirthday = function(arg){
     arg.age = arg.age + 1;
} 

happyBirthday(dog)
console.log(dog)
// Returns 
dog {name: 'Beau', age: 16}

Enter fullscreen mode Exit fullscreen mode

Conclusion

To sum it, when a primitive type is passed into a function, it creates a copy. When we pass an object into a function, it's the same as passing the object itself. Which is something that we should be careful with, as it can again, lead to large issues.

Further Reading

value vs reference

academind

Discussion (0)