# Encapsulation in JavaScript and TypeScript - Simple & Code Example

In this blog post, I will be discussing encapsulation in JavaScript and TypeScript. I will start by defining encapsulation and explaining its importance in software engineering. Then, I will provide code examples of encapsulation in both JavaScript and TypeScript to better illustrate the concept in each scenario. By the end of this post, you should have a solid understanding of how encapsulation works in both languages and how you can use it to create more maintainable and scalable code.

### What is encapsulation?

Encapsulation is an important concept in software engineering that refers to the bundling of data and methods together within a single unit, such as a class or object, and restricting access to those data and methods from outside of that unit. Encapsulation is a fundamental principle of object-oriented programming (OOP) and is used to promote data hiding, reduce code complexity, and increase code reusability.

### Encapsulation in JavaScript

In JavaScript, encapsulation can be achieved through the use of closures and the revealing module pattern. The revealing module pattern is a design pattern that uses closures to create private variables and methods and expose them through a public interface. Here's an example of encapsulation in JavaScript using the revealing module pattern:

```typescript
const counter = (() => {
  let count = 0;

  const getCount = () => count;
  const incrementCount = () => count++;

  return {
    getCount,
    incrementCount,
  };
})();

console.log(counter.getCount()); // 0
counter.incrementCount();
console.log(counter.getCount()); // 1
```

In this example, the `counter` object is created using an immediately-invoked function expression (IIFE) that returns an object with two methods: `getCount` and `incrementCount`. The `count` variable is declared inside the IIFE and is not accessible from outside the `counter` object. This creates a private variable that is encapsulated within the `counter` object.

### Encapsulation in TypeScript

In TypeScript, encapsulation can be achieved using access modifiers, such as `public`, `private`, and `protected`. Access modifiers allow you to control the visibility and accessibility of properties and methods within a class. Here's an example of encapsulation in TypeScript using access modifiers:

```typescript
class Person {
  private name: string;
  private age: number;

  constructor(name: string, age: number) {
    this.name = name;
    this.age = age;
  }

  public getName(): string {
    return this.name;
  }

  public getAge(): number {
    return this.age;
  }

  public setName(name: string): void {
    this.name = name;
  }

  public setAge(age: number): void {
    this.age = age;
  }
}

const person = new Person('Alice', 25);

console.log(person.getName()); // Alice
person.setName('Bob');
console.log(person.getName()); // Bob
```

This example shows a `Person` class with two private properties: `name` and `age`. The class has four methods, two to get the values of the private properties and two to set their values. An instance of the `Person` class is created with the values `'Alice'` and `25`, and the `getName` method is called to get the value of the `name` property. Then, the `setName` method is called with the value `'Bob'`, and the `getName` method is called again to get the updated value.

The `Person` class uses access modifiers to encapsulate the private properties and provide public methods to access and modify their values. The example shows how encapsulation can be used to create a more maintainable and scalable codebase.

In conclusion, encapsulation is an important concept in software engineering that is used to promote data hiding, reduce code complexity, and increase code reusability. In JavaScript, encapsulation can be achieved using closures and the revealing module pattern, while in TypeScript, encapsulation can be achieved using access modifiers such as `public`, `private`, and `protected`. Encapsulation is a fundamental principle of OOP and should be used to create maintainable and scalable software systems.

