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:
-
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.
-
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.
-
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.
-
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