References vs Values in JavaScript

References vs Values in JavaScript

Preface

Different data types are passed either by their value or by their reference. Today, we will look at what this means in JavaScript and how it affects our code. This can be a reason for a lot of bugs in JS and a deeper dive into this will let us understand how it can be avoided and used for our own good.

Pass by value

In JavaScript, primitive data types are passed by copy of their value. These primitive types are, Number, String, Boolean, null and undefined.

let a = 10;
let b = a;

console.log(a);  // 10
console.log(b);  // 10

Here the value of variable a is copied and assigned to variable b. This means that these variables are separate with no relationship with each other. Due to this, changing one variable's value doesn't change the other.

let a = 10;
let b = 20;

a = 30;

console.log(a);  // 30
console.log(b);  // 10

Pass by reference

All the non-primitive types, that is, objects are passed by reference. In JavaScript, arrays and functions are also a type of object. Whenever we assign an object to a variable, the variable contains the address of that object and not the object itself. This address points to the object stored in the memory.

const person = {
    'name': 'vaishnav',
    'age': 20
};

// variable 'person' contains the address of the object

Whenever a variable is assigned to another variable, both the variables will hold the same address and they will be pointing to the same object.

const person1 = {
    'name': 'vaishnav',
    'age': 20
};

const person2 = person1;  // 'person2' contains the same address stored by 'person2'

console.log(person1 === person2);  // true, since they both have the same address

Since both these variables are pointing to the same object, any changes made from one object will be visible by the other object.

const person1 = {
    'name': 'vaishnav',
    'age': 20
};

const person2 = person1; 
person1.age = 35;  // original object modified

console.log(person2.age);  // 35

In the example below, the original variable person1 will hold the address to the new object while the variable person2 will hold the address to the original object. If there was no variable such as person2, that is, if no variable is pointing to an object, then that object will be deleted from memory during Garbage collection.

let person1 = {
    'name': 'vaishnav',
    'age': 20
};

let person2 = person1;
person1 = {
    'name': 'shyam',
    'age': 60
};

console.log(person1);  // {name: 'shyam', age: 60}
console.log(person2);  // {name: 'vaishnav', age: 20}

Function arguments

Everything we discussed above applies for function arguments as well. Primitive data type variables will be passed by copy of their value and any changes made to the local variables inside the function will not affect the actual arguments.

let val = 90;
increment(a);

function increment(a) { 
    a += 10;
    console.log(a);  // 100
}

console.log(val);  // 90

All objects will be passed by their references. In this case, any changes made to the local variable will change the actual variable as they are pointing to the same object. To avoid this, it is advised to use pure functions. Pure function is a function that returns the same result if the same arguments are passed.

const person1 = {
    name: 'vaishnav',
    age: 20
};

alterData(person1);

function alterData(obj) {
    obj.name = "shyam";
    obj.age = 50;
}

console.log(person1); // {name: 'shyam', age: 50}

Conclusion

Today we covered how pass by reference and pass by value works. Understanding this is vital when you are strengthening your fundamentals. If you have anything you’d like to add to this article or any questions, feel free to comment down below.

I am currently posting articles on important JavaScript topics that you need to learn before moving to react. Follow me on twitter to get notified when I post them.