Prototypes in JavaScript
Introduction
Every object has an internal link to another object called its prototype. When you read user.save, JavaScript looks on user, then walks the prototype chain until it finds save or returns undefined. Classes are built on this model—understanding prototypes explains instanceof, method sharing, and inheritance.
Prerequisites
[[Prototype]] and __proto__
// Objects inherit from Object.prototype by default
const obj = { a: 1 };
console.log(Object.getPrototypeOf(obj) === Object.prototype);
const proto = Object.getPrototypeOf(obj);
console.log(proto.toString === Object.prototype.toString);Avoid relying on __proto__ in application code—use Object.getPrototypeOf / Object.setPrototypeOf or classes.
Methods Live on the Prototype
// Constructor function (classic)
function Animal(name) {
this.name = name;
}
Animal.prototype.speak = function () {
return `${this.name} makes a sound`;
};
const dog = new Animal("Rex");
console.log(dog.speak());
console.log(dog.hasOwnProperty("name"));
console.log(dog.hasOwnProperty("speak"));speak is shared by all Animal instances—memory efficient.
Class Desugars to Prototype
// ES6 class — same idea
class Vehicle {
constructor(type) {
this.type = type;
}
info() {
return `Vehicle: ${this.type}`;
}
}
const car = new Vehicle("car");
console.log(Object.getPrototypeOf(car) === Vehicle.prototype);Prototype Chain Lookup
// Inherited method from Object.prototype
const point = { x: 1, y: 2 };
console.log(point.toString());
// Shadowing: own property hides prototype
point.toString = () => "custom";
console.log(point.toString());Object.create
// New object with explicit prototype
const personProto = {
greet() {
return `Hi, ${this.name}`;
},
};
const ada = Object.create(personProto);
ada.name = "Ada";
console.log(ada.greet());Mini Example: Shared Behavior Without Class
// Prototype object for many records
const listMethods = {
add(item) {
this.items.push(item);
},
size() {
return this.items.length;
},
};
function createList() {
const list = Object.create(listMethods);
list.items = [];
return list;
}
const todos = createList();
todos.add("write docs");
todos.add("run build");
console.log(todos.size());FAQ
Prototype vs class?
class is clearer syntax; prototypes are the underlying mechanism.
Can I change a prototype after creating instances?
Yes—existing instances see new methods added to their prototype; be careful in libraries.
Multiple inheritance?
JavaScript has single prototype chain; mixins copy methods onto prototypes or use composition.
What comes next?
Constructors—constructor, new, and static members.