Data types in JavaScript

Data types in JavaScript

In this article, we'll take a closer look at JavaScript data types, which are categorized into two main types: Primitives and Non-Primitives.

Primitives

In JavaScript, we can consider as primitive the following data types:

  • String

  • Number

  • BigInt

  • Boolean

  • Undefined

  • Null

  • Symbol

Primitive values are immutable, passed as values, and have no methods, but what exactly does each of these characteristics mean?

  1. They are immutable:
    The fact of a variable being mutable or immutable is not directly linked to the type of variable (const, let, or var) but rather to the type of data. In JavaScript, primitives are immutable, which means that every time we reassign the value of a variable that can change (let and var), a new value is created and assigned to this variable.

     // When reassigning the value of x, a new value will be created.
     let x = "abc";
     x = x + "d";
    
  2. They are passed by value:
    Primitive types are passed by value, this means that when we provide a primitive value to another function or variable, we are going to provide a copy of our current value, leaving the original unchanged.

     /*
     When passing the variable "val" to the function "timesTwo", the function 
     will work with a copy of "val" instead of the variable itself.
     */
     const val = 10;
    
     function timesTwo(value) { 
         return value * 2;
     }
    
     const result = timesTwo(val);
    
     console.log(result); // 20
     console.log(val);   // 10
    
  3. They have no methods:
    Primitives in JavaScript do not have methods, each primitive type has its corresponding Object, except for null and undefined. This is what allows us to use methods in primitive types. When trying to use a method, JavaScript will wrap the primitive type in its corresponding object, making it possible to do so.

     /*
     The variable "str" is a primitive, so, it doesn't have any methods, but yet we can
     do "str.toUpperCase()", that is because when we call the method, JavaScript will 
     wrap the variable in its corresponding Object, in this case, the String Object.
     */
     const str = "Our string";
     console.log(str.toUpperCase());
    

Objects (Non-primitives)

Going in the opposite way of primitives, Objects are mutable, passed by reference, they have methods, and beyond that, Objects can hold multiple types of data in their structures.

When we talk about objects, we also include arrays and functions. So, as we did before, let’s go through these characteristics.

They are mutable:
Objects are mutable, meaning that when we update a value inside an object, no new object is created. Instead, the existing value in memory is directly updated."

/*
there is no new value being created, for now, you can consider the previous value 
is just being overwritten
*/
const object = {
    value: 10
};

object.value = 20;
💡
This behavior is explained by how JavaScript memory management works for objects and will be explained in another post.

They are passed by reference:
When passing objects to another function or method, the object will be passed by reference, this means that any change that happens will affect the original value. This, also explains why when comparing “identical” JavaScript might tell us they are different

/* 
Both "original" and "reference" point to same memory address, so, changing one
will change the other.
*/

const original = { value: 5 };
const reference = original;

reference.value = 10;

console.log(original); // { value: 10 }
console.log(reference); // { value: 10 }

// By passing the object to the function, we'll change the original value.

function timesTwo(obj) {
 obj.value *= 2;
};

timesTwo(original)

console.log(original); // { value: 20}
console.log(reference); // { value: 20 }

/* 
Since Objects are treated by their reference, when we create two "identical" 
objects they will have different memory addresses, and when we compare them, 
we will be comparing their memory addresses, which is why identical-looking 
objects may not be considered equal.
*/

const arr1 = [1, 2, 3]; // Memory address 0x001
const arr2 = [1, 2, 3]; // Memory address 0x002

console.log(arr1 === arr2) // false -> 0x001 === 0x002

Conclusion

In this article, we've covered the basics of Primitives and Nonprimitives in JavaScript. The goal is to give you a foundation to better understand how JavaScript handles memory for these data types.

I hope this content may help you in some way, and if you have any questions, don’t hesitate to leave a comment.

Thanks!