Primitive vs Reference types in JavaScript

In JavaScript, there are two categories of data types: primitives and reference types.

Primitives are immutable (cannot be changed) and are passed by value.

Boolean, Null, Undefined, Number, String and Symbol come under this category.

Reference types are mutable (can be changed) and are passed by reference.

Object, Array, Function, Date, RegExp and Error fall under this category.

It is important not to confuse a primitive itself with a variable assigned a primitive value. The variable may be reassigned to a new value, but the existing value cannot be changed in the ways that objects, arrays and functions can be altered.

When you pass a primitive to a function or assign it to a variable, a copy of the value is created. When you pass a reference type to a function or assign it to a variable, a reference to the object in memory is created. This means that any changes made to the object will be reflected in all references to that object.

Let's understand this with an example.

let a = 10;

let b = a;

a++;

console.log(a);

console.log(b);

let obj1 = { value: 10 }

let obj2 = obj1;

obj1.value++;

console.log(obj1.value);

console.log(obj2.value);

Output

11

10

11

11

In the first example, a copy of value of `a` is created when it is assigned to `b`, so changing `a` does not affect `b`.

In the second example, `obj1` and `obj2` both reference the same object in memory, so changing a property on `obj1` also changes the same property on `obj2`.

Let's look at another example.

let a = 10;

function increment(a) {

a++;

console.log(a);

}

increment(a);

console.log(a);

Output

11

10

In the above example, when `a` is passed to the `increment()`, another copy of `a` is created. This copy's value is incremented and we get `11`. But the value of `a` in the global space is still `10` and that's what printed next.