Object-Oriented Programming Paradigm
OOP is a paradigm focused on modeling systems as collections of objects, where each object represents a specific aspect of the system's data and behaviour.
"Everything is an object." This assertion underlies Object-Oriented Programming (OOP). In this paradigm, objects are well-defined data structures, each with its own properties (attributes) and the capability to execute its own procedures (methods).
Some of the primary benefits of this approach include well-structured codebases and programs that are easier to modify, debug, maintain, and reuse.
In JavaScript, the class syntax is simply syntactic sugar over function constructors and Prototypal Inheritance. When we share data or functionality between objects —for example, a child object accessing a parent object’s methods or properties —we are utilizing the built-in prototype system.
How the Prototype Chain Works
- When you access a property, the JavaScript interpreter first looks at the instance object itself.
- If the property is not found, it travels up the prototype chain using the proto pointer.
- It searches the linked prototype objects until it finds the property or reaches
Object.prototype(the root). - When a new object is created in JavaScript, we are instantiating a reference to a specific location in memory and its corresponding prototype.
The Four Principles of OOP
The core of OOP is built upon four pillars:
- Encapsulation,
- Abstraction,
- Inheritance, and
- Polymorphism.
1. Encapsulation
Encapsulation ensures that all properties and methods of an object are kept self-contained and protected from outside interference. Within an object, we can define both private and public members.
While private variables and methods are inaccessible to other objects, public ones provide a controlled interface for interaction. This prevents the internal state of an object from being modified unexpectedly by external code.
let employee = {
baseSalary: 50000,
overtime: 10,
rate: 20,
// This method uses 'this' to access its own encapsulated data
getWage: function() {
return this.baseSalary + (this.overtime * this.rate);
}
};
console.log(employee.getWage()); // 50200
2. Abstraction
Abstraction helps isolate the impact of code changes; if an update is made, it only affects the internal implementation details of a class rather than the external code.
Think of a music player: you see a "Play" button, but the complex circuitry required to decode the audio is hidden inside. We interact with the technology on the surface without needing to understand its internal mechanics. By hiding internal complexity and exposing only essential features, we prevent "leaking" implementation details that the rest of the program does not need to manage.
3. Inheritance
Through the inheritance mechanism, a class can derive features, properties, and methods from another class. In JavaScript, this is achieved through the prototype chain. This promotes reusability and ensures that shared functionality is not duplicated in memory.
4. Polymorphism
Polymorphism (meaning "many shapes") allows different objects to be treated as instances of the same general type through a shared interface. It helps eliminate long if/else or switch statements by allowing each unique object to implement its own specific version of a common method. When that method is called, the object performs the action according to its own logic.
Example:
// Each element (Circle, Square, Triangle) has its own render logic,
// but we can call .render() on all of them in one loop.
elements.forEach(element => element.render());
Key Benefits of OOP
- Encapsulation: Reduces complexity and increases reusability.
- Abstraction: Isolates the impact of changes by hiding implementation details.
- Inheritance: Eliminates redundant code by sharing logic across objects.
- Polymorphism: Refactors messy conditional logic into clean, object-specific behaviour.
