Mastering Classes and Object-Oriented Programming in JavaScript
Table of contents
In a world where code is king, mastering classes and object-oriented programming (OOP) in JavaScript can set you apart. If you've ever wondered how experienced developers create clean, reusable code, the answer lies in OOP principles and using JavaScript classes effectively.
Let’s dive into how JavaScript classes work, understand OOP concepts, and explore practical examples to elevate your coding skills.
What is Object-Oriented Programming in JavaScript?
Object-Oriented Programming (OOP) is a paradigm where the code is organized around objects, rather than functions and logic alone. It helps developers create modular code that’s easy to read, manage, and extend. In JavaScript, OOP is implemented using classes, prototypes, and a set of principles like encapsulation, inheritance, and polymorphism.
Core Principles of OOP:
Encapsulation: Group related variables and functions in a single unit, an object, or class.
Inheritance: Allow new classes to extend existing ones, reusing code effectively.
Polymorphism: Give a single interface multiple implementations.
Abstraction: Expose only essential features and hide unnecessary details.
JavaScript Classes: The Building Blocks of OOP
JavaScript classes, introduced in ES6, provide a clean, syntactic sugar to define objects and enable OOP practices. While JavaScript remains a prototype-based language under the hood, classes provide a clearer structure.
Defining a Class in JavaScript
Let’s create a simple Car
class as an example.
class Car {
constructor(brand, model) {
this.brand = brand;
this.model = model;
}
start() {
console.log(`${this.brand} ${this.model} is starting...`);
}
drive() {
console.log(`${this.brand} ${this.model} is on the move!`);
}
}
const myCar = new Car('Toyota', 'Camry');
myCar.start(); // Output: "Toyota Camry is starting..."
myCar.drive(); // Output: "Toyota Camry is on the move!"
The
Car
class has aconstructor
method that initializes its properties (brand
andmodel
). Thestart
anddrive
methods add functionality to instances of theCar
class.
Key Concepts in JavaScript OOP
1. Constructor Functions
The constructor
function is a special method in a class that runs when an object is created. It’s commonly used to set initial properties.
constructor(brand, model) {
this.brand = brand;
this.model = model;
}
Here,
constructor
setsbrand
andmodel
properties when a newCar
instance is created.
2. Encapsulation in JavaScript
Encapsulation lets us bundle data and methods into a single unit. In JavaScript, we can use classes and closures to achieve encapsulation, helping us protect data from unintended modification.
class Car {
constructor(brand, model) {
this._brand = brand;
this._model = model;
}
getDetails() {
return `${this._brand} ${this._model}`;
}
}
The underscore (
_
) prefix conventionally marks properties as private (even though JavaScript doesn’t have true private properties outside of recent#
syntax).
3. Inheritance in JavaScript
Inheritance allows us to create new classes based on existing ones. Let’s create an ElectricCar
class that extends Car
:
class ElectricCar extends Car {
constructor(brand, model, batteryLife) {
super(brand, model); // Call the parent constructor
this.batteryLife = batteryLife;
}
chargeBattery() {
console.log(`Charging the battery of ${this.brand} ${this.model}.`);
}
}
const myElectricCar = new ElectricCar('Tesla', 'Model S', '100 kWh');
myElectricCar.start(); // Inherited method
myElectricCar.chargeBattery(); // New method specific to ElectricCar
Using
extends
andsuper()
,ElectricCar
inherits methods fromCar
, allowing us to reuse code.
4. Polymorphism in JavaScript
Polymorphism lets us define multiple behaviors for the same function, depending on the object’s context. For example:
class Animal {
speak() {
console.log("The animal makes a sound.");
}
}
class Dog extends Animal {
speak() {
console.log("The dog barks.");
}
}
const myDog = new Dog();
myDog.speak(); // Output: "The dog barks."
The
speak
method behaves differently depending on the class (Animal
orDog
), demonstrating polymorphism.
Best Practices for OOP in JavaScript
Use encapsulation to protect object properties.
Keep classes focused on a single responsibility.
Use inheritance thoughtfully to avoid over-complexity.
Write modular, reusable code that can be extended.
Advantages of Using OOP in JavaScript
Code Reusability: Inheritance allows you to reuse existing code across classes.
Code Maintenance: Modular classes make the code easier to read and maintain.
Debugging: Grouping code into classes simplifies the debugging process.
Scalability: OOP helps build scalable, large applications by promoting organized code structure.
Real-World Example: Shopping Cart System
Let’s create a simple shopping cart system to see OOP in action.
class Product {
constructor(name, price) {
this.name = name;
this.price = price;
}
}
class Cart {
constructor() {
this.items = [];
}
addItem(product) {
this.items.push(product);
}
calculateTotal() {
return this.items.reduce((total, product) => total + product.price, 0);
}
}
const apple = new Product('Apple', 0.5);
const bread = new Product('Bread', 2);
const cart = new Cart();
cart.addItem(apple);
cart.addItem(bread);
console.log(`Total: $${cart.calculateTotal()}`); // Output: "Total: $2.5"
In this example:
Product
is a simple class representing an item with a name and price.Cart
is another class that adds products and calculates the total.
JavaScript OOP: Classes vs Functions
Classes in JavaScript offer a more structured approach to creating objects compared to functions alone. While functions can also create objects, classes provide a cleaner syntax and built-in methods, making the code easier to understand and maintain.
// Function-based constructor
function Person(name) {
this.name = name;
}
Person.prototype.greet = function() {
console.log(`Hello, my name is ${this.name}.`);
};
const person1 = new Person('Alice');
person1.greet();
While this approach works, ES6 classes bring more readability and consistency.
Wrapping Up
JavaScript classes and OOP principles like encapsulation, inheritance, and polymorphism can transform your code into an organized, reusable structure that’s easier to maintain and scale.
Whether you’re building complex applications or simpler features, understanding OOP will make you a more effective JavaScript developer.
Subscribe to my newsletter
Read articles from Stanley Owarieta directly inside your inbox. Subscribe to the newsletter, and don't miss out.
Written by
Stanley Owarieta
Stanley Owarieta
𝗔𝘀𝗽𝗶𝗿𝗶𝗻𝗴 𝗙𝗿𝗼𝗻𝘁𝗲𝗻𝗱 𝗗𝗲𝘃𝗲𝗹𝗼𝗽𝗲𝗿 passionate about 𝙅𝙖𝙫𝙖𝙎𝙘𝙧𝙞𝙥𝙩, 𝙘𝙤𝙙𝙞𝙣𝙜, 𝙖𝙣𝙙 𝙗𝙪𝙞𝙡𝙙𝙞𝙣𝙜 𝙢𝙮 𝙛𝙪𝙩𝙪𝙧𝙚 𝙞𝙣 𝙩𝙚𝙘𝙝. Along with my 𝙡𝙤𝙫𝙚 for 𝙛𝙖𝙨𝙝𝙞𝙤𝙣, 𝙜𝙖𝙢𝙞𝙣𝙜, 𝙖𝙣𝙙 𝙡𝙪𝙭𝙪𝙧𝙮 𝙡𝙞𝙫𝙞𝙣𝙜, I have big dreams like 𝙤𝙬𝙣𝙞𝙣𝙜 𝙖 𝙥𝙧𝙞𝙫𝙖𝙩𝙚 𝙟𝙚𝙩 and 𝙡𝙞𝙫𝙞𝙣𝙜 𝙞𝙣 𝙖 𝙡𝙪𝙭𝙪𝙧𝙮 𝙝𝙤𝙢𝙚 𝙤𝙣𝙚 𝙙𝙖𝙮. Since 2021, I’ve invested in 𝗔𝗽𝗽𝗹𝗲, 𝗔𝗺𝗮𝘇𝗼𝗻, 𝗦𝗵𝗼𝗽𝗶𝗳𝘆, 𝗮𝗻𝗱 𝗚𝗼𝗼𝗴𝗹𝗲—working toward financial independence. I also look forward to being a 𝗹𝗼𝘃𝗶𝗻𝗴 𝗳𝗮𝘁𝗵𝗲𝗿 𝗮𝗻𝗱 𝗮 𝗱𝗲𝘃𝗼𝘁𝗲𝗱 𝗽𝗮𝗿𝘁𝗻𝗲𝗿, growing a 𝗺𝗶𝗹𝗹𝗶𝗼𝗻-𝗱𝗼𝗹𝗹𝗮𝗿 𝗯𝗿𝗮𝗻𝗱 together with my 𝗳𝘂𝘁𝘂𝗿𝗲 𝘄𝗶𝗳𝗲. Let’s connect and inspire each other on this journey!