1. Classes and Objects
In JavaScript, a class is essentially a blueprint for creating objects. It defines the structure (properties) and behavior (methods) that the objects created from the class will have.
- Class: It is a function that defines a template for creating objects. A class contains:
- Properties (or attributes) that store data. Methods (or functions) that define the behaviors/actions the object can perform.
- Object: An instance of a class. It is created using the new keyword, and it can access the class properties and methods.
* In the below example, Person is the class. name and age are properties, and greet() is a method that is used to introduce the person.
//Code Example
class Person {
constructor(name, age) {
this.name = name; // property
this.age = age; // property
}
greet() {
console.log(`Hello, my name is ${this.name} and I am ${this.age} years old.`);
}
}
const person = new Person('John Doe', 30);
person.greet();
//Output: Hello, my name is John Doe and I am 30 years old. 2. Constructors
A constructor is a special method in a class that is automatically invoked when a new object is created from that class. It is typically used to initialize the object’s properties.
- Syntax: The constructor is defined using the constructor keyword within the class.
- Usage: It allows you to pass values when creating an object to set the initial state (values) of the properties.
//Code Example
class Person {
constructor(name, age) {
this.name = name; // sets the name property
this.age = age; // sets the age property
}
}
const person = new Person('Alice', 25);
console.log(person.name);
//Output: Alice
console.log(person.age);
//Output: 25 3. Properties
Properties are the data members of an object. They store the current state or attributes of an object. Each object can have its own unique set of properties.
Here, make and model are properties that store the data about the car.
//Code Example
class Car {
constructor(make, model) {
this.make = make; // Property
this.model = model; // Property
}
}
const car = new Car('Toyota', 'Corolla');
console.log(car.make);
//Output: Toyota
console.log(car.model);
//Output: Corolla 4. Methods
Methods are the functions defined inside a class that describe the actions or behaviors of an object. These methods can manipulate the object’s properties or perform specific tasks.
Here, greet() is a method that prints the greeting message, using the object’s properties.
//Code Example
class Person {
constructor(name, age) {
this.name = name;
this.age = age;
}
greet() {
console.log(`Hello, my name is ${this.name} and I am ${this.age} years old.`);
}
}
const person = new Person('Bob', 35);
person.greet();
//Output: Hello, my name is Bob and I am 35 years old. 5. Inheritance
Inheritance is the concept where a class can inherit properties and methods from another class. This helps avoid code duplication by allowing one class (child class) to reuse the properties and methods of another class (parent class).
- The extends keyword is used to create a subclass.
- The super() function is used to call the constructor of the parent class.
Here, Dog inherits the eat() method from the Animal class, but it also has its own method bark().
//Code Example
class Animal {
constructor(name) {
this.name = name;
}
eat() {
console.log(`${this.name} is eating.`);
}
}
class Dog extends Animal {
constructor(name, breed) {
super(name); // Call parent constructor
this.breed = breed;
}
bark() {
console.log(`${this.name} is barking.`);
}
}
const dog = new Dog('Max', 'Golden Retriever');
dog.eat();
//Output: Max is eating.
dog.bark();
//Output: Max is barking. 6. Polymorphism
Polymorphism means “many shapes” in Greek, and in OOP, it allows different classes to implement the same method in different ways. The same method name behaves differently depending on the object.
- It can be achieved through method overriding where a subclass provides a specific implementation of a method already defined in its parent class.
The sound() method is implemented differently in the Dog and Cat subclasses, demonstrating polymorphism.
//Code Example
class Animal {
constructor(name) {
this.name = name;
}
sound() {
console.log(`${this.name} makes a sound.`);
}
}
class Dog extends Animal {
sound() {
console.log(`${this.name} barks.`);
}
}
class Cat extends Animal {
sound() {
console.log(`${this.name} meows.`);
}
}
const animals = [new Dog('Max'), new Cat('Whiskers')];
animals.forEach(animal => {
animal.sound(); // Each animal makes a different sound.
}); 7. Encapsulation
Encapsulation is the concept of bundling the data (properties) and the methods (functions) that operate on the data into a single unit or class. It also involves restricting direct access to some of the object’s components, making the object more secure.
- Access to an object’s internal state is usually restricted, and it is only modified through methods (getters and setters).
In this example, the balance property is encapsulated and can only be modified by calling the deposit() method or accessed via the getBalance() method.
//Code Example
class BankAccount {
constructor(accountNumber, balance) {
this.accountNumber = accountNumber;
this.balance = balance;
}
deposit(amount) {
this.balance += amount;
}
getBalance() {
return this.balance;
}
}
const account = new BankAccount('1234567890', 1000);
account.deposit(500);
console.log(account.getBalance());
//Output: 1500 8. Abstraction
Abstraction is the concept of hiding the complex implementation details and showing only the necessary and relevant features of an object. It focuses on what an object does, rather than how it does it.
- Abstract classes are often used to provide a common interface for all subclasses while hiding the details.
Here, the Car class provides an abstraction of the car’s operations. The user interacts with the methods startEngine() and accelerate(), without needing to understand the internal implementation of these actions.
//Code Example
class Car {
constructor(make, model, year) {
this.make = make;
this.model = model;
this.year = year;
}
startEngine() {
console.log('The engine is started.');
}
accelerate() {
console.log('The car is accelerating.');
}
}
const car = new Car('Toyota', 'Camry', 2015);
car.startEngine();
//Output: The engine is started.
car.accelerate();
//Output: The car is accelerating. 9. Real-World Applications of OOP in JavaScript
Object-Oriented Programming is widely used in modern JavaScript development, especially when building large, scalable applications. Frameworks like React, Angular, and Vue.js all incorporate OOP principles at their core. For example, React components can be considered as classes or objects — each with their own state (properties) and lifecycle methods (behaviors). This approach makes it easier to break down a complex UI into smaller, reusable pieces.
In backend development, Node.js also leverages OOP principles. Developers can create modular classes for database connections, user authentication, or API responses, which can be reused and extended across the application. This structure enhances maintainability and reduces code duplication.
10. Advantages of Using OOP in JavaScript
OOP brings several benefits that make development more structured and efficient:
Reusability: Classes and methods can be reused across projects, reducing redundant code.
Maintainability: Encapsulation ensures that changes in one part of the code do not affect others.
Scalability: OOP supports modular architecture, making it ideal for large applications.
Code Clarity: By modeling real-world entities as objects, the code becomes more intuitive and easier to understand.
Extensibility: Inheritance and polymorphism allow developers to extend functionality without rewriting existing code.
These advantages make OOP an essential paradigm for writing clean, efficient, and easily testable JavaScript programs.
11. ES6 Features That Enhance OOP
With the introduction of ECMAScript 6 (ES6), JavaScript gained several features that make implementing OOP concepts easier and more powerful. These include:
Class syntax: Simplifies object creation and inheritance.
Arrow functions: Provide concise syntax and automatically bind
this.Modules: Allow separation of class definitions into different files for better organization.
Getters and Setters: Enable controlled access to object properties, promoting encapsulation.
Static methods: Belong to the class itself rather than to instances, useful for utility functions.
Together, these ES6 features make JavaScript a fully capable OOP language, comparable to Java or Python in design flexibility.
12. Best Practices for OOP in JavaScript
When using OOP in JavaScript, follow these best practices to ensure clean and efficient code:
Use meaningful class names that represent real-world entities.
Keep methods focused on a single responsibility to maintain clarity.
Encapsulate data by using private fields (using
#syntax) and expose them through getters and setters.Prefer composition over inheritance when possible, to make code more flexible.
Document your classes with comments or JSDoc to make them easy to understand.
Following these principles ensures that your OOP-based JavaScript applications are scalable, readable, and easier to maintain in the long run.
Conclusion
Object-Oriented Programming in JavaScript provides a powerful way to structure code by organizing data and behavior together. By mastering classes, inheritance, encapsulation, and abstraction, developers can write cleaner and more efficient programs. As modern JavaScript continues to evolve with ESNext features, understanding OOP will remain a core skill for building robust, interactive, and professional-grade web applications.