Object-Oriented Programming (OOP) is a programming paradigm that has stood the test of time, and for good reason. It provides a structured approach to organizing code, making it more modular, reusable, and easier to maintain. While JavaScript isn't a traditional class-based OOP language, it offers powerful ways to implement OOP concepts. Let's dive into the world of OOP in vanilla JavaScript!
At the heart of OOP in JavaScript are objects. These are collections of key-value pairs that can represent real-world entities or abstract concepts. Here's a simple example:
const car = { brand: 'Toyota', model: 'Corolla', year: 2022, start: function() { console.log('Engine started!'); } }; console.log(car.brand); // Output: Toyota car.start(); // Output: Engine started!
Objects can contain properties (like brand
and year
) and methods (like start
). This encapsulation of data and behavior is a fundamental principle of OOP.
Before the introduction of classes in ES6, constructor functions were the primary way to create object templates in JavaScript:
function Car(brand, model, year) { this.brand = brand; this.model = model; this.year = year; } Car.prototype.start = function() { console.log('Engine started!'); }; const myCar = new Car('Honda', 'Civic', 2023); myCar.start(); // Output: Engine started!
Here, Car
is a constructor function, and we've added a method to its prototype. This approach allows all instances of Car
to share the start
method, saving memory.
ES6 introduced the class
syntax, providing a more familiar way for developers from other OOP languages to work with JavaScript:
class Car { constructor(brand, model, year) { this.brand = brand; this.model = model; this.year = year; } start() { console.log('Engine started!'); } static numberOfWheels() { return 4; } } const myCar = new Car('Tesla', 'Model 3', 2023); myCar.start(); // Output: Engine started! console.log(Car.numberOfWheels()); // Output: 4
Classes in JavaScript are syntactic sugar over the prototype-based inheritance but provide a cleaner, more intuitive syntax. Note the static
method, which belongs to the class itself, not instances of the class.
Inheritance allows us to create new classes based on existing ones, promoting code reuse. In JavaScript, we use the extends
keyword:
class ElectricCar extends Car { constructor(brand, model, year, batteryCapacity) { super(brand, model, year); this.batteryCapacity = batteryCapacity; } charge() { console.log('Charging the battery...'); } } const myTesla = new ElectricCar('Tesla', 'Model S', 2023, '100kWh'); myTesla.start(); // Output: Engine started! myTesla.charge(); // Output: Charging the battery...
The ElectricCar
class inherits properties and methods from Car
while adding its own unique features.
Encapsulation is about bundling data and the methods that operate on that data within one unit, like a class. It also involves controlling access to that data. JavaScript doesn't have built-in private properties, but we can simulate them:
class BankAccount { #balance = 0; // Private field constructor(owner) { this.owner = owner; } deposit(amount) { if (amount > 0) { this.#balance += amount; console.log(`Deposited ${amount}. New balance: ${this.#balance}`); } } getBalance() { return this.#balance; } } const account = new BankAccount('Alice'); account.deposit(100); console.log(account.getBalance()); // Output: 100 console.log(account.#balance); // Error: Private field
The #balance
is a private field, accessible only within the BankAccount
class. This prevents direct manipulation of the balance from outside the class, maintaining data integrity.
Polymorphism allows objects of different types to be treated as objects of a common super class. In JavaScript, this is often achieved through method overriding:
class Animal { speak() { console.log('The animal makes a sound'); } } class Dog extends Animal { speak() { console.log('The dog barks'); } } class Cat extends Animal { speak() { console.log('The cat meows'); } } const animals = [new Animal(), new Dog(), new Cat()]; animals.forEach(animal => animal.speak()); // Output: // The animal makes a sound // The dog barks // The cat meows
Each subclass overrides the speak
method, allowing for different behaviors while maintaining a common interface.
By incorporating these OOP principles into your vanilla JavaScript code, you can create more structured, maintainable, and scalable applications. Remember, the goal is not just to use these concepts, but to use them effectively to solve real-world problems and improve your codebase.
15/10/2024 | VanillaJS
22/10/2024 | VanillaJS
14/09/2024 | VanillaJS
15/10/2024 | VanillaJS
15/10/2024 | VanillaJS
22/10/2024 | VanillaJS
22/10/2024 | VanillaJS
15/10/2024 | VanillaJS
22/10/2024 | VanillaJS
15/10/2024 | VanillaJS