⚡ JavaScript

OOP: Classes and Objects in JavaScript (Node.js): A Detailed Guide

What is it and why? (a real-life analogy)

Imagine you decided to build a city from LEGO bricks. You have a box of parts, and you can assemble anything from them: a house, a car, a tree. But every time you need a new car, you don't disassemble the old one and rebuild it from scratch — you just take a blueprint (instruction) and assemble another identical car using it.

In programming, a class is exactly that blueprint or instruction. And an object is a specific car assembled from that blueprint. If the blueprint says the car must have wheels, a steering wheel, and headlights, then every assembled car will have these parts. But the color of the headlights or the size of the wheels may differ between cars — these are the properties of the object.

Why is this needed? Imagine you are writing a program for an online store. You have thousands of products. Each product has a name, price, description, and image. If you wrote code without OOP, you would have to create a bunch of separate variables and functions for each product. But with classes, you describe the "product blueprint" once, and then create as many product objects as you need. This saves time, reduces the number of errors, and makes the code understandable.

💡 Important: OOP (Object-Oriented Programming) is not some special language, but a way of thinking about a program. You are learning not just to write code, but to design a system of interacting "building blocks" — objects.

Theory: how it works internally

Let's look "under the hood" of JavaScript and understand what actually happens when we create a class and an object.

What is a class really?

In JavaScript, a class is a special kind of function. When you write class User { ... }, JavaScript creates a function named User. But this function is not ordinary — it has a special property prototype that stores all the methods of the class.

What is an object?

An object is a set of properties (key: value). When you create an object via new User(), the following happens:

  1. An empty object {} is created
  2. A prototype is attached to this object (a reference to User.prototype)
  3. The constructor function (the constructor method) is called, which fills the object with data
  4. The object is returned and saved into a variable

Prototypal inheritance

JavaScript does not have "real" classes like Java or C++. It uses prototypal inheritance. This means that if an object does not have a certain property, JavaScript looks for it in the prototype (parent), then in the prototype of the prototype, and so on, until it finds it or reaches null.

// Example of a prototype chain
const animal = {
    eats: true
};

const rabbit = {
    jumps: true
};

// Setting the prototype: rabbit inherits from animal
rabbit.__proto__ = animal;

console.log(rabbit.jumps); // true — own property
console.log(rabbit.eats);  // true — taken from the animal prototype
⚠️ Important: The __proto__ property is deprecated. In modern JS, Object.getPrototypeOf() and Object.setPrototypeOf() are used, and for classes — extends.

How does JavaScript store methods?

Class methods are not copied into each object. They are stored in one place — in ClassName.prototype. All objects of the same class reference the same prototype. This saves memory: if you have 1000 objects, the methods are not duplicated 1000 times.

Syntax in JavaScript (Node.js): all forms and variations

In JavaScript, there are several ways to create a class and an object. Let's look at all the main options.

1. Classic syntax (ES6+)

The most modern and understandable way is to use the class keyword.

// Declaring a class
class Book {
    // Constructor — called when creating an object
    constructor(title, author, year) {
        this.title = title;      // this — reference to the object being created
        this.author = author;
        this.year = year;
        this.isAvailable = true; // default property
    }

    // Class method
    getInfo() {
        return `${this.title} — ${this.author} (${this.year})`;
    }

    // Another method
    borrow() {
        if (this.isAvailable) {
            this.isAvailable = false;
            return `You borrowed the book "${this.title}"`;
        } else {
            return `The book "${this.title}" is already taken`;
        }
    }
}

// Creating objects (instances of the class)
const book1 = new Book('War and Peace', 'Leo Tolstoy', 1869);
const book2 = new Book('Crime and Punishment', 'Fyodor Dostoevsky', 1866);

console.log(book1.getInfo()); // "War and Peace — Leo Tolstoy (1869)"
console.log(book1.borrow());  // "You borrowed the book "War and Peace""
console.log(book1.borrow());  // "The book "War and Peace" is already taken"

2. Constructor function (old way, ES5)

Before the class keyword appeared in JavaScript, regular functions were used.

// Constructor function
function Car(brand, model, year) {
    this.brand = brand;
    this.model = model;
    this.year = year;
    this.mileage = 0;
}

// Methods are added to prototype
Car.prototype.getFullName = function() {
    return `${this.brand} ${this.model} (${this.year})`;
};

Car.prototype.drive = function(km) {
    this.mileage += km;
    return `Mileage now: ${this.mileage} km`;
};

// Creating an object
const myCar = new Car('Toyota', 'Camry', 2020);
console.log(myCar.getFullName()); // "Toyota Camry (2020)"
console.log(myCar.drive(150));    // "Mileage now: 150 km"