Object Prototypes
I. What is a prototype?
Every JavaScript object has an internal link to another object called its prototype. When you access a property or method on an object, JavaScript first checks the object itself. If it does not find it there, it looks up the prototype chain until it either finds the property or reaches null.
This is how built-in methods work. When you call [1, 2, 3].map(...), map lives on Array.prototype, not on the array itself. JavaScript finds it by walking up the chain.
II. Adding methods to the prototype
When you put methods inside a constructor function, each new instance gets its own copy. That wastes memory. A better approach is to add methods to the constructor’s prototype property so all instances share one copy.
function Person(firstName, lastName, birthDay) {
this.firstName = firstName;
this.lastName = lastName;
this.birthDay = new Date(birthDay);
}
Person.prototype.getFullName = function () {
return `${this.firstName} ${this.lastName}`;
};
Person.prototype.getBYear = function () {
return this.birthDay.getFullYear();
};
const p1 = new Person("Anna", "Wood", "3-25-1995");
const p2 = new Person("Joe", "Hopkins", "10-12-1990");
console.log(p1.getFullName()); // Anna Wood
console.log(p2.getBYear()); // 1990
getFullName and getBYear live on Person.prototype. Every Person instance can call them, but they only exist in one place.
III. Inspecting the prototype chain
console.log(Object.getPrototypeOf(p1) === Person.prototype); // true
console.log(p1.hasOwnProperty("firstName")); // true
console.log(p1.hasOwnProperty("getFullName")); // false (it's on the prototype)
IV. The modern alternative
Prototype manipulation directly is uncommon in new code. ES6 classes provide the same behaviour with simpler syntax. Under the hood, they still use the prototype chain.
class Person {
constructor(firstName, lastName, birthDay) {
this.firstName = firstName;
this.lastName = lastName;
this.birthDay = new Date(birthDay);
}
getFullName() {
return `${this.firstName} ${this.lastName}`;
}
getBYear() {
return this.birthDay.getFullYear();
}
}
Class methods are added to the prototype automatically. See Classes for the full class syntax.