Understanding JS primitives

chandrasekarg profile image Chandrasekar Gokulanathan ・3 min read

JavaScript is a loosely typed language. Hence it's very easy for developers to overlook the need to understand its data types. But as we go on to work with different JS frameworks and libraries, the raw knowledge of JS becomes imperative to grasp their nuances.

Let's start from the very basics. We'll question our knowledge and try to answer them along our way.

Data Types

We all know that there is no static typing in JS. Meaning, developers cannot enforce the data type of variables before-hand. It'll always be inferred by JS at run-time.

// Static typing - not possible in JS
int noOfYears = 5;
string name = 'Code';

// Dynamic typing
var noOfYears = 5;
typeof noOfYears;       //  "number"
var name = 'Code';
typeof name;            //  "string"

The typeof operator returns us a string indicating the type of the variable JS has evaluated at run-time.

Q1 : So, how many data types does JS know to evaluate our variables?

There are 7 primitive types and an Object type.

Primitive types

  1. number
  2. bigint
  3. string
  4. boolean
  5. null
  6. undefined
  7. symbol

When we say primitive it means,

  • The values are represented directly at the lowest level of the language implementation.
  • They are immutable (i-e) they cannot be altered.
  • They are always copied by value instead of reference.
  • They do not have any associated functions to perform operations on them.

Q2: What does immutability really mean here? Because, when I assign a number to a variable and then re-assign it to a different value, everything seems to work great. In the example below, a is mutable right?

var a = 5;
console.log(a); //  5
a = 25;
console.log(a); //  25

Great question indeed. It is true that you are able to change the value of a from 5 to 25. But here, it is important not to confuse a primitive itself with a variable assigned a primitive value.

5 is primitive. Whereas the variable a which has a primitive value of 5 is not a primitive. It's just a variable that supposedly has a primitive value.

If it's still confusing, consider this,

You can in no way change the value of 5. It's always 5 whatever we do with it. The fundamental meaning of the value of 5 cannot be changed by you no matter what.

Consider a string which again is immutable. In the example below, even if we try to modify the string, since its immutable it doesn't change its value.

var animal = "Cat";
console.log(animal[0]); //  C
animal[0] = "R";
console.log(animal); // Cat

Summing up, Values are immutable. Variables are not. They just hold a reference to their (primitive) values.

Q3: Are variables really call by value? Because I remember any changes made to a variable getting reflected in its reference.

This is again a general confusion with developers. Primitives are always copied by value and not by reference. Because, if it's by reference, then they become mutable.

The reference change which people often mention happens with Object types. The example below will make it clear

// Primitive types - Call by Value

var a = 5;
var b = a;
console.log(a); //  5
console.log(b); //  5

b = 100;
console.log(a); //  5
console.log(b); //  100

// Object types - Call by reference

var a = { val: 5 };
var b = a;

b.val = 100;
console.log(a); //  {val: 100}
console.log(b); //  {val: 100}

Here, when we assign a to b, the value of a is copied by value. That is why any changes done to b does not really affect a. Whereas that is not the case if a is an Object.

Q4: I've performed operations with primitive types. The toUpperCase() is one example. Then how are that primitives don't have any associated functions with them?

Short answer - JavaScript promptly coerces between primitives and objects.

JS has a few wrapper objects around primitive types. Number is a wrapper around number type. String is a wrapper around string type. These wrappers belong to Object type and have corresponding functionalities to those primitives.

So, lets consider an example,

var animal = "Cat";
console.log(animal.toUpperCase()); // CAT
console.log(animal); // Cat

So, the toUpperCase() actually belongs to the String wrapper object and not the string primitive type.

So,this is what roughly happens behind the scenes,

var animal = "Cat";
var tempVar = new String(animal);

I hope this has cleared a few confusions with primitives. Feel free to comment on any other questions/corrections you may have!


Posted on by:

chandrasekarg profile

Chandrasekar Gokulanathan


Full stack Web and Cross-Platform Mobile Developer


Editor guide

Thanks! Great article. This will come in handy with my students.


Glad it was of some help :)