DEV Community

Jin Vincent Necesario
Jin Vincent Necesario

Posted on • Originally published at lock29down.Medium on

OOP in JavaScript: Prototype vs Class

A beginner-friendly guide to how objects and inheritance work in JavaScript.


Photo by Growtika on Unsplash

Introduction

JavaScript remains one of the most popular languages today, and it often confuses people when discussing Object-Oriented Programming (OOP) within it.

You may be asking, “Why”? It is because JavaScript uses prototype-based OOP, not the traditional class-based OOP like Java or C#.

People are thinking about TypeScript.

To remove the confusion.

Since TypeScript is a superset of JavaScript, it fully respects JavaScript’s underlying prototype-based inheritance model.

Still, TypeScript adds class-based OOP features (like in Java or C#) for cleaner syntax and static typing, but it doesn’t remove or replace prototypes — everything still compiles down to JavaScript.

Saying this just to be clear.

What is OOP?

This section could be a good review or refresher for those who are already experts.

OOP stands for Object Oriented Programming, a way of writing code where you group related data and functions into objects.

These objects can hold data known as properties, can perform actions known as methods, and inherit from other objects.

In traditional languages like C#, we can create a class as a blueprint, then create objects from that class.

Think of it like baking cookies from a mold.

public class Vehicle
{
    public string Name { get; set; }
    public int Speed { get; set; }
    public void Accelerate(int increaseSpeed)
    {
        if (increaseSpeed > 0)
        {
            this.Speed = this.Speed + increaseSpeed;
        }
    }
}

public class Truck: Vehicle
{
    public void Break(int decreaseSpeed)
    {
        if (decreaseSpeed > 0)
        {
            this.Speed = this.Speed - decreaseSpeed;
        }
    }
}
Enter fullscreen mode Exit fullscreen mode

From our example above, it is a straightforward class in C#.

What’s Happening in ES6 Classes?

In TypeScript or JavaScript (ES6 onward), we can now use a similar class-based style.

Let’s try to mimic the example from C#.

class Vehicle {
  constructor(name, speed = 0) {
    this.name = name;
    this.speed = speed;
  }

  accelerate(increaseSpeed) {
    if (increaseSpeed > 0) {
      this.speed += increaseSpeed;
    }
  }
}

class Truck extends Vehicle {
  brake(decreaseSpeed) {
    if (decreaseSpeed > 0) {
      this.speed -= decreaseSpeed;
    }
  }
}

// Example usage:
const myTruck = new Truck("Fuso", 40);
myTruck.accelerate(20);
console.log(`${myTruck.name} speed: ${myTruck.speed}`); // Fuso speed: 60
myTruck.brake(10);
console.log(`${myTruck.name} speed: ${myTruck.speed}`); // Fuso speed: 50
Enter fullscreen mode Exit fullscreen mode

Looks great? Right?

Now, here’s the twist: before ES6, JavaScript didn’t have class.

That’s why in the old days, creating a similar example would be built using functions and prototypes.

Moreover, this class syntax in ES6 is a syntactic sugar — it makes the code easier to write and read, especially for developers like us who came from class-based languages like C# or Java.

Furthermore, the ES6 class under the hood translates into prototype chaining.

Therefore, JavaScript (ES6) still employs prototype-based inheritance internally, even with the use of syntactic sugar in the form of classes.

That’s a good understanding of it, still, or will be a good thing under your belt.

Prototype-Based Version of Vehicle and Truck

Let’s try to see the example converted into the original prototype-based version of the vehicle and truck.

// Constructor function for Vehicle
function Vehicle(name, speed = 0) {
  this.name = name;
  this.speed = speed;
}

// Add method to Vehicle's prototype
Vehicle.prototype.accelerate = function(increaseSpeed) {
  if (increaseSpeed > 0) {
    this.speed += increaseSpeed;
  }
};

// Constructor function for Truck (inherits from Vehicle)
function Truck(name, speed) {
  // Call Vehicle constructor
  Vehicle.call(this, name, speed);
}

// Set Truck prototype to inherit from Vehicle's prototype
Truck.prototype = Object.create(Vehicle.prototype);
// Fix constructor reference
Truck.prototype.constructor = Truck;

// Add method to Truck prototype
Truck.prototype.brake = function(decreaseSpeed) {
  if (decreaseSpeed > 0) {
    this.speed -= decreaseSpeed;
  }
};

// Example usage:
const myTruck = new Truck("Fuso", 40);
myTruck.accelerate(20);
console.log(`${myTruck.name} speed: ${myTruck.speed}`); // Fuso speed: 60
myTruck.brake(10);
console.log(`${myTruck.name} speed: ${myTruck.speed}`); // Fuso speed: 50
Enter fullscreen mode Exit fullscreen mode

As we have converted our example, the first thing to note is that there’s no class; it uses constructor functions and, of course, prototypes are manually implemented.

Moreover, it is verbose, but it provides a clear view of how inheritance works in JavaScript.

If you try to run the code sample, you’ll see something similar to this, see the screenshot below.

As you can see, the inheritance is done by linking prototypes; the internal property [[Prototype]] points to another object.

This prototype chain syntax is complicated to read, but it can be modified at runtime with flexibility.

Summary & Key Takeaways

JavaScript is prototype-based at its core.

Even though ES6 introduced class syntax, it’s just syntactic sugar over the prototype-based inheritance system that JavaScript has always used.

ES6 classes look familiar to developers with backgrounds in Java, C#, or TypeScript, which improves code readability and structure; however, under the hood, it’s still all about prototypes.

TypeScript provides a class-based feel with static typing, but it compiles down to JavaScript, meaning prototypes are still in effect—nothing magical, just a developer-friendly layer.

Understanding how both class-based and prototype-based OOP work in JavaScript helps you:

  • Debug more effectively
  • Write more optimized and flexible code
  • Appreciate how modern JavaScript builds on its core foundations

Final Note

Whether you prefer writing in ES6 classes or the old-school prototype way, knowing what’s happening under the hood gives you a serious edge as a JavaScript developer.

This information, code, or software is provided for informational purposes only. It should not be considered professional coding or legal advice. Not all code or information provided may be accurate or suitable for your project. Consult a software development expert or legal professional before making significant coding or legal decisions.

Top comments (0)