Beginner's Guide to OOP in JavaScript
Tags: javascript, oop, webdev, programming
Published: 2022-05-22 18:12:42

## Object-Oriented Programming (OOP)?

Object-oriented programming is a type of paradigm based on an "object" in a  programming language that contains data known as attributes and code known as methods.

## Philosophy

Object-oriented programming is based on the 4 principles:

- **Abstraction**

Objects only reveal internal mechanisms that are relevant for the use of other objects, hiding any unnecessary implementation code.

- **Encapsulation**

To prevent some of the properties or methods of an object to access outside of its scope. It resists mutating these encapsulated properties or methods outside its scope.


- **Inheritance**

To inherit methods from a blueprint object. It features the reusability of a method from a blueprint object where it is defined originally.


- **Polymorphism**

Polymorphism is considered one of the important features of Object-Oriented Programming. Polymorphism allows us to perform a single action in different ways. In other words, polymorphism allows you to define one interface and have multiple implementations. The word “poly” means many and “morphs” means forms, So it means many forms.

## Implementation of OOP in JavaScript

Javascript is an OOP-based programming language so it follows the same philosophy as a typical OOP language, but the implementation is slightly different.

### Inheritance and the Prototype Chain

Prototypes are the mechanism by which JavaScript objects inherit features from one another. When it comes to inheritance, JavaScript only has one construct: *objects*. Each object has a private property that holds a link to another object called its prototype. That prototype object has a prototype of its own, and so on until an object is reached with null as its prototype. By definition, null has no prototype and acts as the final link in this prototype chain.

Nearly all objects in JavaScript are instances of Object, which has null as its prototype.

The heart of an OOP programming language is the object. So let's discuss it.

### Object

An Object is a unique entity that contains property and methods. For example “car” is a real-life Object, which has some characteristics like color, type, model, and horsepower and performs certain actions like driving. 

In JavaScript, we can implement OOP in JavaScript in following ways:

- Construction Function Method
- Object.create Method
- ES6 Class Method

let's discuss them one by one.

- **Construnction Function Method**

In JavaScript, you can create multiple objects from a constructor function. To create an object from a constructor function, we use the `new` keyword.

```javascript
const Person = function (firstName, birthYear) {
  this.firstName = firstName;
  this.birthYear = birthYear;  
}
//here person is a construction function
//for creating construction function, function declaration or function expression is used. Arrow can not be used because it doesn't have "this" keyword

Person.prototype.calcAge = function() {
  return console.log(`Age: ${2020 - this.birthYear}`);
}
//using the prototype object, a new method is created to person function, which can be used for all the instances

const Student = function (firstName, birthYear, course) {
  this.firstName = firstName;
  this.birthYear = birthYear;
  this.course = course;
};
Student.prototype = Object.create(Person.prototype);
//Student extends to Person

Student.prototype.greet = function () {
  return console.log(`Hi, I am ${this.firstName} and I study ${this.course}.`);
};


const ram = new Student('Ram', 2000, 'computer science'); //new instance 'ram' is created

ram.calcAge() // 20
ram.greet() //Hi, I am Ram and I study computer science.
console.log(ram instanceof Student) //true
console.log(ram instanceof Person) //true

```
Here is a prototype chain created.

ram -> Student -> Person -> Object

we can check it using `__proto__` property.

```javascript

console.log(ram.__proto__ === Student.prototype) //true
console.log(ram.__proto__.__proto__ === Person.prototype) //true
console.log(ram.__proto__.__proto__.__proto__ === Object.prototype) //true

```


- **Object.create Method**

The `Object.create()` method creates a new object, using an existing object as the prototype of the newly created object.

```javascript

const Person = {
  init(firstName, birthYear) {
    this.firstName = firstName;
    this.birthYear = birthYear
  },
  calcAge() {
    return console.log(`Age: ${2020 - this.birthYear}`);
  }
}

const Student = Object.create(Person)

Student.init = function(firstName, birthYear, course) {
  this.firstName = firstName;
  this.birthYear = birthYear;
  this.course = course
}

Student.greet = function() {
  return console.log(`Hi, I am ${this.firstName} and I study ${this.course}.`);
}

const ram = Object.create(Student)
ram.init('Ram', 2000, 'Computer Science')

ram.calcAge() //Age: 20
ram.greet() //Hi, I am Ram and I study computer science.

```

- **ES6 Class Method**

Classes are a template for creating objects. They encapsulate data with code to work on that data. Classes in JS are built on prototypes.

```javascript

class Person {
  constructor(fullName, birthYear) {
    this.fullName = fullName;
    this.birthYear = birthYear;
  }

  calcAge() {
    return console.log(`Age: ${2020 - this.birthYear}`);
  } 
}

class Student extends Person {
  constructor(fullName, birthYear, course) {
    super(fullName, birthYear);
    this.course = course;
  }

  greet() {
    console.log(`Hi there, I am ${this.fullName} and I study ${this.course}.`);
  }
}

const ram = new Student('Ram', 2000, 'Computer Science')

ram.greet() //Hi there, I am Ram and I study Computer Science.
ram.calcAge() //Age: 20

```

## Static Method and Property

The static keyword defines a static method or property for a class. Neither static methods nor static properties can be called on instances of the class. Instead, they're called on the class itself.

```javascript

class Person {
  constructor(fullName, birthYear) {
    this.fullName = fullName;
    this.birthYear = birthYear;
  }
  static property = 'some value';

  calcAge() {
    console.log(`Age: ${2020 - this.birthYear}`);
  } 

  static method() {
    console.log('this is a static method')
  }
}

const ram = new Person('Ram', 2000)

console.log(ram.property) //throws an error
console.log(ram.calcAge()) //Age: 20
console.log(ram.method()) //throws an error

```

## Private Class Feature

Class fields are public by default, but private class members can be created by using a hash `#` prefix. The privacy encapsulation of these class features is enforced by JavaScript itself.

```javascript

class Person {
  constructor(fullName, birthYear) {
    this.fullName = fullName;
    this.birthYear = birthYear;
  }
  #property = 'some value';

  calcAge() {
    console.log(`Age: ${2020 - this.birthYear}`);
    console.log(this.#property)
  } 
}

const ram = new Person('Ram', 2000)

console.log(ram.#property) //throws an error
//Error: Private field '#property' must be declared in an enclosing class

ram.calcAge()
//Age: 20
//some value

```

This blog is all about a brief introduction to OOP in JavaScript. For more details about this topic, read on [MDN Web Docs](https://developer.mozilla.org/en-US/).