• JavaScript Video Tutorials

JavaScript - Encapsulation



What is Encapsulation?

Encapsulation in JavaScript is a way to keep the related properties and methods under a single namespace by bundling them. It can be a function, a class or an object. In JavaScript, the encapsulation can be implemented using closures, classes and getters and setters.

Encapsulation is a fundamental concept in Object-oriented programming languages, along with inheritance and polymorphism. JavaScript is an object oriented programming language.

It is used to hide the data from the outside world and give access to required data only to improve the integrity and security of the data.

What is the need for encapsulation?

Let's discuss the need for encapsulation in JavaScript via the following example.

For example, you have defined the below object in your code.

const car = {
   Brand: "Honda city",
   model: "sx",
   year: 2016,
}

Anyone can access the properties of the car object, as shown below.

car.Brand

Also, anyone can change the value of any property of the car object, as shown below.

car.Brand = true;

Here, the value of the Brand property is changed to the boolean from the string. So, it is required to secure the original data of the object and give limited access to the data to the outside world.

In this situation, the concept of encapsulation comes into the picture.

Different Ways to Achieve Encapsulation in JavaScript

There are three different ways to achieve encapsulation.

  • Using the function closures

  • Using the ES6 classes

  • Using the Getters and Setters

Here, we will learn each approach for achieving encapsulation one by one.

Achieving Encapsulation Using the Function Closures

A JavaScript function closure is a concept allowing the inner function to access the variable defined in the outer function even after the outer function is executed. The variables defined in the outer function can't be accessed outside its functional scope but can be accessed using the inner scope.

Example

In the below code, shoppingCart() function is an outer function that contains the variables and function. The outer function has its private scope.

The carItems[] array is used to store the shopping cart's items.

The add() function can access the carItems[] array and add items.

The remove() function checks whether the cartItems[] contains the items you need to remove. If yes, it removes the item. Otherwise, it prints the message that you can't remove the item.

The shoppingCart() function returns the object containing the add() and remove() functions.

After creating a new instance of the shoppingCart() function, you can use the add() and remove() functions to manipulate the shopping cart data.

<html>
<body>
  <p id = "output"> </p>
  <script>
    let output = document.getElementById("output");
    function shoppingCart() {
      const cartItems = [];
      function add(item) {
        cartItems.push(item);
        output.innerHTML += `${item.name} added to the cart. <br>`;
      }
      function remove(itemName) {
        const index = cartItems.findIndex(item => item.name === itemName);
        if (index !== -1) {
          const removedItem = cartItems.splice(index, 1)[0];
          output.innerHTML += `${removedItem.name} removed from the cart. <br>`;
        } else {
          output.innerHTML += `Item ${itemName} not found in the cart. <br>`;
        }
      }
      return {
        add,
        remove,
      };
    }

    // Defining items
    const item1 = { name: 'Car', price: 1000000 };
    const item2 = { name: 'Bike', price: 100000 };
    // Create a new Shopping cart
    const cart = shoppingCart();
    // Adding items to the cart
    cart.add(item1);
    cart.add(item2);
    // Remove bike from the cart
    cart.remove('Bike');
  </script>
</body>
</html>

Output

Car added to the cart.
Bike added to the cart.
Bike removed from the cart.

In this way, no one can directly access and modify the cartItems[] array.

Achieving Encapsulation Using ES6 Classes and Private Variables

In JavaScript, you can use classes and private variables to achieve the encapsulation.

Private Variables (Fields) in JavaScript

To define the private class variables, you can write a variable name followed by the ‘#’ sign. For example, 'name' is a private variable in the below code.

class car {
    #name= "TATA";
}

If you try to access the name by the instance of the class, it will give you an error that private fields can't be accessed outside the class.

To achieve encapsulation, you can define the private variables in the class and give them access to the outside world using different methods.

Example

In the example below, we have defined the car class.

The car class contains the 'brand', 'name', and 'milage' private variables.

The getMilage() method is defined to return the milage of the car, and the setMilage() method is used to set the milage of the method.

We created the car class's object and used the method to access and modify the private fields. If you try to access the private field of the class, the code will throw an error.

You can also define more methods in the class to access and modify other private fields.

<html>
<body>
  <div id = "output1">The car mileage is:  </div>
  <div id = "output2">After updating the car mileage is:  </div>
  <script>
    class Car {
      #brand = "TATA"; // Private field
      #name = "Nexon"; // Private field
      #milage = 16;    // Private field

      getMilage() {
        return this.#milage; // Accessing private field
      }

    setMilage(milage) {
      this.#milage = milage; // Modifying private field
    }
    }

    let carobj = new Car();
    document.getElementById("output1").innerHTML += carobj.getMilage();
    carobj.setMilage(20);
    document.getElementById("output2").innerHTML += carobj.getMilage();
    // carobj.#milage);  will throw an error.
  </script>
</body>
</html>

Output

The car mileage is: 16
After updating the car mileage is: 20

Achieving Encapsulation Using the Getters and Setters

The JavaScript getters and setters can be defined using the get and set keywords, respectively. The getters are used to get the class properties, and setters are used to update the class properties.

They are very similar to the class methods but defined using the get/set keyword followed by the method name.

Example

In the example below, we have defined the User class containing the three private fields named username, password, and isLoggedIn.

The getters and setters named username are defined to get and set user names. Here, you can observe that name of the getters and setters method is the same.

After that, we create an object of the class and use the getters and setters as the property to access and update the username field of the class.

You may also create getters and setters for the other class fields.

<html>
<body>
    <div id = "output1">The initial username is:  </div>
    <div id = "output2">The new username is:  </div>
    <script>
        class User {
            #username = "Bob";
            #password = "12345678";
            #isLoggedIn = false;
            get username() {
                return this.#username;
            }

            set username(user) {
                this.#username = user;
            }
        }

        const user = new User();
        document.getElementById("output1").innerHTML += user.username;
        user.username = "Alice";
        document.getElementById("output2").innerHTML += user.username;
    </script>
</body>
</html>

Output

The initial username is: Bob
The new username is: Alice

From the above all, you can understand that encapsulation is making variable privates and restricting its access to the outside world.

Benefits of Encapsulation in JavaScript

Here, we have listed some benefits of encapsulation in JavaScript −

  • Data protection − The encapsulation allows you to control the access of the class data by making them private. You can expose the required data and methods only. So, no one can modify the data by mistake. Also, you can validate the data while updating them. If new data is not valid, you can throw an error.

  • Code reusability − The class is a template for the object, and you can reuse it to create objects with different data.

  • Code Maintenance − The encapsulation makes it easy to maintain the code as each object is independent, and if you make changes to one object, it doesn't affect the other code.

Advertisements