DEV Community

Cover image for Encapsulation Explained using JavaScript
Akpevwe11
Akpevwe11

Posted on

Encapsulation Explained using JavaScript

Encapsulation is one of the fundamental principles of object-oriented programming (OOP) that refers to the concept of binding the data (member variable) and the methods that operate on the data (member functions) within a single unit called a class.

Encapsulation enables programmers to hide the implementation details of one object from other objects and restrict direct access to the internal state of an object.

Encapsulation provides several benefits, such as:

  • improving the maintainability of the code -- making it easier to modify and extend the class's functionality.

  • Enhancing the security of the data by preventing unauthorized access.

  • It also allows the programmer to use the class's interface without knowing the implementation details, which makes it easier to use and understand.

let look at an example of encapsulation in JavaScript:

function createCounter() {
  let count = 0;

  function increment() {
    count++;
    console.log(count);
  }

  return increment;
}

const counter = createCounter();

counter(); // Output: 1
counter(); // Output: 2
counter(); // Output: 3


Enter fullscreen mode Exit fullscreen mode

In this example, we have a createCounter function that returns an increment function. The increment function has access to the count variable through a closure, but the count variable is not accessible from outside the function. The only way to modify the count variable is by calling the increment function, which increments the count and logs it to the console.
This is an example of encapsulation because the count variable is hidden from the outside world and can only be accessed through the increment function, which provides a well-defined interface for accessing and modifying the count.

In addition to using closures, another way to achieve encapsulation in JavaScript is by using setters and getters. Setters and getters are methods that allow us to control how properties are set and retrieved from an object.

Here's an example of encapsulation using setters and getters:

class Person {
  constructor(name, age) {
    this._name = name;
    this._age = age;
  }

  get name() {
    return this._name;
  }

  set name(newName) {
    if (typeof newName === "string") {
      this._name = newName;
    } else {
      throw new Error("Name must be a string");
    }
  }

  get age() {
    return this._age;
  }

  set age(newAge) {
    if (typeof newAge === "number" && newAge > 0) {
      this._age = newAge;
    } else {
      throw new Error("Age must be a positive number");
    }
  }
}

const person = new Person("John Doe", 30);
console.log(person.name); // Output: John Doe
console.log(person.age); // Output: 30

person.name = "Jane Doe";
person.age = 25;

console.log(person.name); // Output: Jane Doe
console.log(person.age); // Output: 25

person.name = 123; // Throws an error: Name must be a string
person.age = -1; // Throws an error: Age must be a positive number

Enter fullscreen mode Exit fullscreen mode

In this example, we have a Person class with name and age properties that are encapsulated using setters andgetters. The getters allow us to retrieve the values of these properties, while the setters allow us to control how they are set.

For instance, the name setter checks whether the new value is a string before setting the _name property, while the age setter checks whether the new value is a positive number. This allows us to enforce certain constraints on the values of these properties and ensure that they are always valid.

By encapsulating thename and age properties using setters and getters, we can hide their internal implementation and control how they are accessed and modified from outside the class. This helps to maintain the integrity of the object and prevent any unexpected side-effects that could result from direct manipulation of its properties.

In Summary, In encapsulation can be achieved through the use of closures and modules, as well as using setters and getters to control how properties are set and retrieved from an object. it also helps to improve the quality and maintainability of software systems.

Top comments (8)

Collapse
 
ravavyr profile image
Ravavyr

I am not a fan of javascript terminology, however you wrote a nice explanation.

To me, encapsulation is just "when you use a function within a function or a class" the end.

Collapse
 
efpage profile image
Eckehard

Did you notice that there is a difference between classes and and objects? You can define a function within a class, but you cannot use it there. You will need to create an instance of the class (-> an object) to "use" a class method. But each object hast it´s individual, separated namespace and memory. THAT makes the difference.

Collapse
 
ravavyr profile image
Ravavyr

Frankly, it makes ZERO difference in about 99% of code any of us ever write. On rare ocassions you might create something where the memory usage actually affects performance, and then you generally just rewrite it or split it into more objects or functions and get it working better.

My comment was just about how javascript terminology sucks and really we don't need many of the terms with really complicated explanations when "a function within a function or class" suffices, that's all.

Collapse
 
efpage profile image
Eckehard

Encapsulation is especially helpful if you need to maintain a larger codebase. It may help you to create better maintainable code.

As long as you need to deal with JS and HTML, your options are a bit limited, as HTML "ID´s" are always defined in a global scope. If you work with dynamically generated DOM elements, this is a different game, as you can encapsulate the DOM-references too. See this example to get an idea of the possibilities.

If you want to work seamless with OO-code on the web, you would need a framework that allows to create the DOM without HTML. There are several approaches to achieve this, like ReDom or DML, which work pretty well to create fully responsive apps.

Collapse
 
peerreynders profile image
peerreynders • Edited

If you want to work seamless with OO-code on the web

Square peg in a round hole

Object-oriented development is good at providing a human oriented representation of the problem in the source code but bad at providing a machine representation of the solution. It is bad at providing a framework for creating an optimal solution.

ref

The browser is a machine:

  • (1) that is incredibly efficient at parsing complex semi-structured data in the form of server-rendered HTML (not to be confused with DOM operations) that can be thought of as the initial rendering for a fresh interaction done on a server with access to better and more determistic computational resources than some indeterminate client device.
  • (2) that is incredibly efficient at parsing CSS and applying the resulting styling rules to the currently rendered semi-structured data, in order to shape that information in a that way more easily comprehended by that indeterminate user of the client device.
  • (3) that features a language runtime that can manipulate the browser's resources and the rendered representation of the semi-structured data.

The "Human Interaction Component" in the days of Coad and Yourdon (1991) was largely based on the mental model of MVC—Smalltalk. Not something like a web browser.

[Progressive enhancement is] a philosophy that recognizes the nature of the Web as a medium and asks us to think about how to build products that are robust and capable of reaching as many potential customers as possible. It isn’t concerned with any particular technology, it simply asks that we look at each tool we use with a critical eye and consider both its benefits and drawbacks. And it’s certainly not anti-JavaScript.

Progressive Misconceptions

React's component model is essentially React style OO-thinking in pursuit of the elusive (composability and) reusability benefit.

But even that component model is showing it's cracks especially when everything is dogmatically coerced into being components or hooks for the sake of interoperability with the framework (reminiscent of the early days of Java were everything had to be an object).

Sure, we need boundaries but those boundaries don't necessarily manifest themselves just in the form of objects.

Application Holotypes: A Guide to Architecture Decisions

Collapse
 
efpage profile image
Eckehard

C++ is good at providing a human oriented representation of the problem in the source code but bad at providing a machine representation of the solution. So, should we use Assembler again? I assume, before ChatGPT most web designers have been humans, so what is bad about a human oriented representation of a problem?

React was not designed to deliver an "optimal" solution. It was designed to make things simpler, even at the price of a high workload to do all the DOM diffing. Browsers are so increadible powerful today, why should we need an "optimal" solution? It´s perfectly ok if it´s simple and understandable.

Thread Thread
 
peerreynders profile image
peerreynders • Edited

Browsers are so incredibly powerful today, why should we need an "optimal" solution?

“… static web site. You see in the trace what's going on here is a badly configured Angular application. It's easy to fix but they just don't have a reason to care, this isn't their problem. Right, it's fast on their iPhone!

Alex Russell - The Mobile Web: MIA - YouTube

Responsive Design didn't work, at least not the way we tried to apply it as a community. How do we know? Because nearly a decade after we adopted it as our p...

favicon youtube.com

Clean Code Q & A

Clean Code Q & A Part 2


This is why performance matters

Collapse
 
peerreynders profile image
peerreynders • Edited

Perhaps you'd like to entertain a slightly different perspective:

"Simple Made Easy" - Rich Hickey (2011) - YouTube

Rich Hickey, the author of Clojure and designer of Datomic, is a software developer with over 30 years of experience in various domains. Rich has worked on s...

favicon youtube.com

Objects were just made to encapsulate IO devices. … They were never supposed be applied to information and we apply them to information. That's it's just wrong.