What sets primitive types apart from objects in JavaScript? Let’s take a closer look.

First, let’s define what primitive types are:

  • Strings
  • Numbers (Number and BigInt)
  • Booleans (true or false)
  • Undefined
  • Symbol values

While null is considered a special primitive type, calling typeof null actually returns 'object', even though it is a primitive type.

In JavaScript, anything that is not a primitive type is an object, including functions. Functions can have properties and methods assigned to them. Although typeof returns 'function' for functions, the Function constructor derives from the Object constructor.

The main differences between primitive types and objects are as follows:

  1. Immutable vs. Mutable: Primitive types are immutable, meaning their values cannot be changed. On the other hand, objects have an immutable reference, but their values can be modified over time.

  2. Pass by Value vs. Pass by Reference: Primitive types are passed by value, meaning a copy of the value is sent to a new location. Objects, however, are passed by reference, which means that the reference to the object is passed, not the actual object.

  3. Copy by Value vs. Copy by Reference: When a primitive type is copied, it is done by value. On the other hand, when an object is copied, it is done by reference. So, assigning an object to a new variable simply creates a reference to the same object.

  4. Comparison by Value vs. Comparison by Reference: Primitive types are compared by value, comparing the actual values they hold. Objects, however, are compared by reference, checking if they refer to the same object in memory.

For example, if we copy a primitive type like this:

let name = 'Flavio';
let secondName = name;

We can change the name variable by assigning it a new value, but secondName will still hold the old value because it was copied by value:

name = 'Roger';
secondName; //'Flavio'

On the other hand, if we have an object like this:

let car = {
  color: 'yellow'
};

And we copy it to another variable like this:

let car = {
  color: 'yellow'
};

let anotherCar = car;

In this case, anotherCar points to the same object as car. If we change the color property of car like this:

car.color = 'blue';

The value of anotherCar.color will also be 'blue'.

The same behavior applies when passing objects to functions and when comparing them. If we compare car to anotherCar like this:

anotherCar === car; // true

This is true because both variables point to the exact same object. However, if anotherCar was an object with the same properties as car, the comparison would yield false:

let car = {
  color: 'yellow'
};

let anotherCar = {
  color: 'yellow'
};

anotherCar === car; // false