Class vs. Prototype: What’s the Difference in JavaScript?

erikzhao
4 min readFeb 16, 2021

If you’re learning JavaScript, one important thing to always remember is that JavaScript is a prototype-based language: when objects are created, the object will instantly have a prototype. The use of this prototype is it holds the properties and methods an object has; JavaScript looks through the prototype to see if the property/method exists. This is where JavaScript distinguishes itself from other languages that are class-based.

An array is created and under _proto_ (array and Object()) you can see all the methods that exist for this object

Well, if JavaScript is prototype-based, does that mean that it does not support classes? No, it does not. Thanks to ECMAScript 2015, programmers can write cleaner and reusable classes that are similar to those in C++ and Java. Let’s take a look at an example:

class EmployeeC {
constructor(name, age) {
this.name = name
this.age = age
}

greeting() {
console.log(`Hello, my name is ${this.name} and I am ${this.age} years old.`)
}

}
let Jared = new EmployeeC ("Jared", 26)
let Jenny = new EmployeeC ("Jenny", 71)
Jared.greeting() // "Hello, my name is Jared and I am 26 years old."
Jenny.greeting() // "Hello, my name is Jenny and I am 71 years old."

In the above example, I create a class EmployeeC and properties in this class with the constructor function, name and age as well as the method greeting(). Afterwards I instantiate the class twice by creating two people, Jared and Jenny. If I console.log() the methods for both people, I would get the method to execute with their respective names and ages.

Now let’s look at the same example, but instead of using classes I’ll use prototypes:

let EmployeeP = function(name, age) {
this.name = name
this.age = age
}
EmployeeP.prototype.greeting = function() {
console.log(`Hello, my name is ${this.name} and I am ${this.age} years old.`)
}
let Jared = new EmployeeP ("Jared", 26)
let Jenny = new EmployeeP ("Jenny", 71)
Jared.greeting() // "Hello, my name is Jared and I am 26 years old."
Jenny.greeting() // "Hello, my name is Jenny and I am 71 years old."

There are several distinctions in terms of how the code is written. Firstly, EmployeeP is not a class, rather it is a function.

Secondly, the class example is actually storing more space than the prototype example. This might be confusing because we are essentially writing the same code, but to understand why this is it’s important to understand how the prototype chain works. Let’s dig deeper into the EmployeeC classes:

Both Jared and Jenny share the same greeting() method, but the method is stored in both of these classes. For the prototypes:

The method is not stored in each new EmployeeP. Instead it’s stored in the EmployeeP _proto_. Here, the distinctions are clear. Say we were to make a 100 EmployeeCs; we would have 100 greeting()s. This is highly inefficient. Why would we want 1 method to take up so much storage? This would just be redundant. However, if we were to make 100 EmployeePs we would not have 100 greeting()s. Instead we would only have one because it would exist in the prototype. This is a key differentiator between JavaScript and other programming languages. Using prototypal inheritance is way more efficient than using class inheritance. It’s simpler and yet more powerful. This is not to say that prototypal inheritance is always superior; Other languages like Python has a strong classical inheritance system but to JavaScript, just using the word class can be harmful.

--

--