DEV Community

Sai Swaroop Bijinapalli
Sai Swaroop Bijinapalli

Posted on

Prototype&Object-oriented Js

Prototypes & Object-Oriented JavaScript: A Complete Beginner's Guide

JavaScript is one of the most popular programming languages for web development. One of its most powerful features is its support for Object-Oriented Programming (OOP). Unlike languages such as Java or C++, JavaScript uses a prototype-based inheritance model. In ES6, JavaScript introduced classes, making OOP easier to understand while still using prototypes internally.

In this blog, we'll explore Prototypes, Prototype Chain, Object.create(), Classes, Inheritance, Static Members, Getters & Setters, and Encapsulation with simple examples.


What is Object-Oriented Programming (OOP)?

Object-Oriented Programming is a programming style where we organize code using objects.

An object contains:

  • Properties (Data)
  • Methods (Functions)

Example

const student = {
    name: "Sai",
    age: 21,

    study() {
        console.log("Studying JavaScript...");
    }
};
Enter fullscreen mode Exit fullscreen mode

Here,

  • name and age are properties
  • study() is a method

Memory representation:

student
│
├── name → "Sai"
├── age → 21
└── study() → Function
Enter fullscreen mode Exit fullscreen mode

Objects help us group related data and behavior together.


The Problem Without Prototypes

Imagine creating multiple student objects.

const student1 = {
    name: "Sai",
    study() {
        console.log("Studying...");
    }
};

const student2 = {
    name: "Rahul",
    study() {
        console.log("Studying...");
    }
};
Enter fullscreen mode Exit fullscreen mode

Both objects contain their own copy of the study() function.

If you create 1000 students, JavaScript creates 1000 identical functions.

student1
│
└── study()

student2
│
└── study()

student3
│
└── study()
Enter fullscreen mode Exit fullscreen mode

This wastes memory.

JavaScript solves this using Prototypes.


What is a Prototype?

A prototype is an object that allows other objects to inherit its properties and methods.

Instead of copying methods into every object, JavaScript stores them once in the prototype.

Example

const person = {

    greet() {
        console.log("Hello!");
    }

};

const student = Object.create(person);

student.name = "Sai";

student.greet();
Enter fullscreen mode Exit fullscreen mode

Output

Hello!
Enter fullscreen mode Exit fullscreen mode

Memory

student
│
├── name → Sai
│
▼
Prototype

person
│
└── greet()
Enter fullscreen mode Exit fullscreen mode

Notice that greet() exists only once.


What is the Prototype Chain?

Whenever JavaScript cannot find a property inside an object, it searches the object's prototype.

This search continues until the property is found or until JavaScript reaches null.

Example

const person = {

    greet() {
        console.log("Hello");
    }

};

const student = Object.create(person);

student.greet();
Enter fullscreen mode Exit fullscreen mode

Search process:

student

↓

person

↓

Object.prototype

↓

null
Enter fullscreen mode Exit fullscreen mode

This searching mechanism is called the Prototype Chain.


Understanding Object.create()

Object.create() creates a new object using another object as its prototype.

Syntax

Object.create(prototypeObject)
Enter fullscreen mode Exit fullscreen mode

Example

const animal = {

    eat() {
        console.log("Eating...");
    }

};

const dog = Object.create(animal);

dog.eat();
Enter fullscreen mode Exit fullscreen mode

Output

Eating...
Enter fullscreen mode Exit fullscreen mode

Memory

dog

↓

animal

↓

eat()
Enter fullscreen mode Exit fullscreen mode

This promotes code reuse.


Constructor Functions

Before ES6 classes, JavaScript developers used constructor functions.

Example

function Student(name, age) {

    this.name = name;
    this.age = age;

}

const s1 = new Student("Sai", 21);
const s2 = new Student("Rahul", 20);
Enter fullscreen mode Exit fullscreen mode

Methods were attached using the prototype.

Student.prototype.study = function () {
    console.log("Studying...");
};
Enter fullscreen mode Exit fullscreen mode

Both objects now share one copy of study().


Classes in JavaScript

ES6 introduced the class keyword.

A class is simply syntactic sugar over JavaScript's prototype system.

Example

class Student {

    constructor(name, age) {

        this.name = name;
        this.age = age;

    }

    study() {

        console.log("Studying...");

    }

}
Enter fullscreen mode Exit fullscreen mode

Creating an object

const s1 = new Student("Sai", 21);
Enter fullscreen mode Exit fullscreen mode

Internally JavaScript still creates prototype-based objects.


Understanding the Constructor

The constructor initializes object properties.

Example

class Student {

    constructor(name) {

        this.name = name;

    }

}

const s = new Student("Sai");
Enter fullscreen mode Exit fullscreen mode

Whenever new Student() is executed, the constructor runs automatically.


Inheritance

Inheritance allows one class to acquire properties and methods from another class.

JavaScript uses the extends keyword.

Example

class Animal {

    eat() {
        console.log("Eating...");
    }

}

class Dog extends Animal {

}

const d = new Dog();

d.eat();
Enter fullscreen mode Exit fullscreen mode

Output

Eating...
Enter fullscreen mode Exit fullscreen mode

Memory

Dog

↓

Animal

↓

eat()
Enter fullscreen mode Exit fullscreen mode

Dog inherits the eat() method from Animal.


The super Keyword

When a child class defines its own constructor, it must call the parent constructor using super().

Example

class Animal {

    constructor(name) {

        this.name = name;

    }

}

class Dog extends Animal {

    constructor(name) {

        super(name);

    }

}
Enter fullscreen mode Exit fullscreen mode

Without super(), JavaScript throws an error because the parent object has not been initialized.


Static Members

Static methods belong to the class itself rather than its objects.

Example

class Calculator {

    static add(a, b) {

        return a + b;

    }

}

console.log(Calculator.add(10, 20));
Enter fullscreen mode Exit fullscreen mode

Output

30
Enter fullscreen mode Exit fullscreen mode

Notice we call the method using the class name.

Calculator.add()

✔ Correct

new Calculator().add()

✖ Wrong
Enter fullscreen mode Exit fullscreen mode

Static methods are useful for utility functions.


Getters and Setters

Getters allow us to read data like a property while executing a function.

Example

class Student {

    constructor(name) {

        this._name = name;

    }

    get name() {

        return this._name;

    }

}

const s = new Student("Sai");

console.log(s.name);
Enter fullscreen mode Exit fullscreen mode

Output

Sai
Enter fullscreen mode Exit fullscreen mode

Setter example

class Student {

    constructor(name) {

        this._name = name;

    }

    set name(value) {

        this._name = value;

    }

}

const s = new Student("Sai");

s.name = "Rahul";

console.log(s.name);
Enter fullscreen mode Exit fullscreen mode

Output

Rahul
Enter fullscreen mode Exit fullscreen mode

Setters are commonly used for validation.


Encapsulation

Encapsulation means hiding internal data and exposing only controlled methods to access or modify it.

A real-life example is an ATM.

You cannot directly change your account balance.

Instead, you use operations such as:

  • Deposit
  • Withdraw
  • Check Balance

Encapsulation Using Closures

Before private fields existed, JavaScript used closures.

function Bank() {

    let balance = 1000;

    return {

        deposit(amount) {

            balance += amount;

        },

        getBalance() {

            return balance;

        }

    };

}

const account = Bank();

account.deposit(500);

console.log(account.getBalance());
Enter fullscreen mode Exit fullscreen mode

Output

1500
Enter fullscreen mode Exit fullscreen mode

Trying to access

console.log(account.balance);
Enter fullscreen mode Exit fullscreen mode

Output

undefined
Enter fullscreen mode Exit fullscreen mode

The variable balance remains private.


Private Fields (#)

Modern JavaScript introduced private class fields using #.

Example

class Bank {

    #balance = 1000;

    deposit(amount) {

        this.#balance += amount;

    }

    getBalance() {

        return this.#balance;

    }

}

const account = new Bank();

console.log(account.getBalance());
Enter fullscreen mode Exit fullscreen mode

Output

1000
Enter fullscreen mode Exit fullscreen mode

Trying to access

console.log(account.#balance);
Enter fullscreen mode Exit fullscreen mode

produces a syntax error because private fields are accessible only inside the class.


Prototype vs Class

Prototype Class
Core inheritance mechanism Cleaner ES6 syntax
Uses prototype objects Uses class keyword
More verbose Easier to read
Supports inheritance Internally uses prototypes

Closures vs Private Fields

Closures Private Fields
Function-based Class-based
Uses lexical scope Uses # syntax
Older approach Modern approach
Good for factory functions Best for classes

Key Takeaways

  • JavaScript objects store data and behavior together.
  • Prototypes allow multiple objects to share methods efficiently.
  • The Prototype Chain is how JavaScript searches for missing properties.
  • Object.create() creates objects that inherit from other objects.
  • Classes provide a cleaner syntax while still using prototypes internally.
  • Inheritance allows child classes to reuse parent functionality.
  • super() calls the parent constructor.
  • Static methods belong to the class, not its instances.
  • Getters and setters provide controlled access to object properties.
  • Encapsulation protects internal data using closures or private fields (#).

Conclusion

Understanding prototypes is the foundation of mastering JavaScript's object-oriented features. While ES6 classes make the language easier to read and write, it's important to remember that classes are simply a cleaner syntax built on top of JavaScript's prototype system. Once you understand prototypes, concepts like inheritance, encapsulation, static methods, getters, and setters become much easier to grasp.

Top comments (0)