Object-Oriented Programming (OOP) is a powerful paradigm that allows developers to create modular, reusable, and maintainable code. In JavaScript, OOP is achieved through classes, objects, inheritance, and more. This article will guide you through the fundamentals of OOP in JavaScript with clear examples and explanations.
Table of Contents
Introduction to OOP
Object-Oriented Programming is a programming paradigm that uses objects and classes to model real-world concepts. It emphasizes data encapsulation, inheritance, and polymorphism, making code easier to understand and maintain.
JavaScript supports OOP through its class syntax, introduced in ES6. Before classes, JavaScript used prototypes for OOP, but classes provide a more familiar syntax for developers coming from other OOP languages.
Key Concepts in OOP
1. Classes and Objects
A class is a blueprint for creating objects. It defines the properties (data) and methods (functions) that an object will have.
// Define a class
class Car {
constructor(brand, model) {
this.brand = brand;
this.model = model;
}
// Method to display information
displayInfo() {
console.log(`Car: ${this.brand} ${this.model}`);
}
}
// Create an object
const myCar = new Car('Toyota', 'Corolla');
myCar.displayInfo(); // Output: Car: Toyota Corolla
2. Constructors
The constructor method is called when an object is created from a class. It initializes the object’s properties.
// Constructor example
class Person {
constructor(name, age) {
this.name = name;
this.age = age;
}
}
const person1 = new Person('Alice', 30);
3. Methods
Methods are functions defined inside a class. They define the behavior of the objects created from the class.
// Method example
class Calculator {
add(a, b) {
return a + b;
}
}
const calc = new Calculator();
console.log(calc.add(5, 3)); // Output: 8
4. Inheritance
Inheritance allows a class (subclass) to inherit properties and methods from another class (superclass). This promotes code reuse.
// Inheritance example
class Animal {
constructor(name) {
this.name = name;
}
speak() {
console.log(`${this.name} makes a sound.`);
}
}
// Subclass
class Dog extends Animal {
speak() {
console.log(`${this.name} barks.`);
}
}
const dog = new Dog('Buddy');
dog.speak(); // Output: Buddy barks.
5. Encapsulation
Encapsulation refers to bundling data (properties) and methods that operate on the data within a single unit (class). It also involves controlling access to the data.
// Encapsulation example
class BankAccount {
constructor(balance) {
this.balance = balance; // Public property
this.#accountNumber = '12345'; // Private property (ES6)
}
deposit(amount) {
this.balance += amount;
}
withdraw(amount) {
if (amount <= this.balance) {
this.balance -= amount;
}
}
}
const account = new BankAccount(1000);
account.deposit(500);
console.log(account.balance); // Output: 1500
6. Abstraction
Abstraction hides complex details and shows only the necessary information to the user. It simplifies the interaction with objects.
// Abstraction example
class Shape {
constructor() {
this.name = 'Shape';
}
// Abstract method (to be implemented by subclasses)
area() {
throw new Error('Method not implemented');
}
}
// Subclass implementing area
class Circle extends Shape {
constructor(radius) {
super();
this.radius = radius;
}
area() {
return Math.PI * this.radius * this.radius;
}
}
const circle = new Circle(5);
console.log(circle.area()); // Output: 78.5398...
7. Polymorphism
Polymorphism allows methods to do different things based on the object they are called on. This is often achieved through inheritance and method overriding.
// Polymorphism example
class Vehicle {
drive() {
console.log('Vehicle is moving.');
}
}
class Car extends Vehicle {
drive() {
console.log('Car is driving on the road.');
}
}
class Boat extends Vehicle {
drive() {
console.log('Boat is sailing on the water.');
}
}
const vehicle = new Vehicle();
const car = new Car();
const boat = new Boat();
vehicle.drive(); // Output: Vehicle is moving.
car.drive(); // Output: Car is driving on the road.
boat.drive(); // Output: Boat is sailing on the water.
Examples of OOP in JavaScript
Example 1: Creating a Simple Class
// Define a class
class Student {
constructor(name, age) {
this.name = name;
this.age = age;
}
introduce() {
console.log(`My name is ${this.name} and I am ${this.age} years old.`);
}
}
// Create an object
const student1 = new Student('John', 20);
student1.introduce(); // Output: My name is John and I am 20 years old.
Example 2: Using Inheritance
// Define a base class
class Animal {
constructor(name) {
this.name = name;
}
eat() {
console.log(`${this.name} is eating.`);
}
}
// Define a subclass
class Dog extends Animal {
constructor(name, breed) {
super(name);
this.breed = breed;
}
bark() {
console.log('Woof!');
}
}
// Create an object
const dog = new Dog('Buddy', 'Golden Retriever');
dog.eat(); // Output: Buddy is eating.
dog.bark(); // Output: Woof!
Example 3: Real-World Application
// Define a base class for bank accounts
class BankAccount {
constructor(accountNumber, balance) {
this.accountNumber = accountNumber;
this.balance = balance;
}
deposit(amount) {
this.balance += amount;
console.log(`Deposited ${amount}. New balance: ${this.balance}`);
}
withdraw(amount) {
if (amount > this.balance) {
console.log('Insufficient funds.');
return;
}
this.balance -= amount;
console.log(`Withdrew ${amount}. New balance: ${this.balance}`);
}
}
// Define a subclass for savings accounts
class SavingsAccount extends BankAccount {
constructor(accountNumber, balance, interestRate) {
super(accountNumber, balance);
this.interestRate = interestRate;
}
addInterest() {
const interest = this.balance * this.interestRate;
this.deposit(interest);
}
}
// Create a savings account
const account = new SavingsAccount('12345', 1000, 0.05);
account.addInterest();
// Output: Deposited 50. New balance: 1050
Frequently Asked Questions
1. What is the difference between a class and an object?
A class is a blueprint or template for creating objects, while an object is an instance of a class. The class defines the properties and methods, and the object is the actual instance that can be manipulated.
2. How does inheritance work in JavaScript?
Inheritance in JavaScript is achieved using the extends
keyword to create subclasses. The super
keyword is used to call the constructor of the superclass and access its methods.
3. What is encapsulation?
Encapsulation is the bundling of data (properties) and methods within a single unit (class). It also involves controlling access to the data, often using access modifiers (public, private, protected).
4. Why is OOP important in JavaScript?
OOP in JavaScript helps in creating modular, reusable, and maintainable code. It allows developers to model real-world concepts and promotes code organization and clarity.
5. How do I create private methods in JavaScript?
Private methods in JavaScript can be created using the #
symbol before the method name, introduced in ES6.
class Counter {
#count = 0;
increment() {
this.#count++;
}
getCount() {
return this.#count;
}
}
const counter = new Counter();
counter.increment();
console.log(counter.getCount()); // Output: 1
Conclusion
Object-Oriented Programming is a fundamental concept in JavaScript that enables developers to create organized, reusable, and maintainable code. By understanding and implementing classes, objects, inheritance, encapsulation, and other OOP principles, you can write cleaner and more efficient code. Start applying these concepts in your projects to take your JavaScript skills to the next level!