How JavaScript Prototype-based Inheritance Works Behind the Scenes

JavaScript fundamentally differs from traditional class-based languages like Java or C++. Although modern ECMAScript standards introduced the class keyword, JavaScript remains a prototype-based language under the hood.

Every JavaScript object has a secret internal property (referred to as [[Prototype]] in the specification) that points to another object. When we try to access a property or method on an object, the JavaScript engine first looks for it on the object itself. If it doesn't find it, it steps up the prototype chain and checks the parent object, continuing until it reaches the end of the chain (which is usually Object.prototype, whose prototype is null).

Practical Example of Using Prototypes

function Developer(name, language) {
    this.name = name;
    this.language = language;
}

// Adding a method to the prototype for memory efficiency
Developer.prototype.introduce = function() {
    return "Hi, my name is " + this.name + " and I code in " + this.language + ".";
};

const peter = new Developer("Peter", "JavaScript");
console.log(peter.introduce());

If we had defined the introduce method directly inside the constructor using the this.introduce = ... syntax, the function would be recreated in memory every single time a new instance is created. By using the prototype, the method is created only once, and all instances share it together.