On this page
Prototypes and Inheritance
JavaScript uses prototype-based inheritance. Every object has an internal link to another object called its prototype. When you access a property, JavaScript looks up the prototype chain until it finds the property or reaches null.
The Prototype Chain
let animal = {
eats: true,
walk() {
console.log('Walking...');
}
};
let rabbit = {
jumps: true,
__proto__: animal // for demo; use Object.create in production
};
rabbit.walk(); // 'Walking...' — found on animal prototype
console.log(rabbit.eats); // true
In modern code, use Object.create or classes instead of __proto__.
Object.create
let animal = {
eats: true,
walk() {
console.log('Animal walks');
}
};
let rabbit = Object.create(animal);
rabbit.jumps = true;
rabbit.walk(); // 'Animal walks'
Constructor Functions and prototype
Before ES6 classes, constructors defined shared methods on prototype:
function Person(name, age) {
this.name = name;
this.age = age;
}
Person.prototype.greet = function() {
console.log(`Hello, I'm ${this.name}`);
};
let alice = new Person('Alice', 25);
alice.greet(); // "Hello, I'm Alice"
console.log(alice.__proto__ === Person.prototype); // true
console.log(Person.prototype.constructor === Person); // true
instanceof
Checks whether an object’s prototype chain includes a constructor’s prototype:
console.log(alice instanceof Person); // true
console.log(alice instanceof Object); // true
Classes Are Syntactic Sugar
ES6 classes are built on prototypes:
class Person {
constructor(name, age) {
this.name = name;
this.age = age;
}
greet() {
console.log(`Hello, I'm ${this.name}`);
}
}
class Employee extends Person {
constructor(name, age, role) {
super(name, age);
this.role = role;
}
describe() {
console.log(`${this.name} is a ${this.role}`);
}
}
let bob = new Employee('Bob', 30, 'Developer');
bob.greet(); // from Person prototype
bob.describe(); // from Employee prototype
Object Methods for Prototypes
let obj = { a: 1 };
let proto = { b: 2 };
Object.getPrototypeOf(obj); // current prototype
Object.setPrototypeOf(obj, proto); // change prototype (use sparingly)
Object.create(proto); // create with given prototype
Person.prototype.hasOwnProperty('greet'); // true on instance via chain
obj.hasOwnProperty('a'); // true — own property only
Mixins
Combine behavior from multiple sources:
let canEat = {
eat() { console.log('Eating...'); }
};
let canWalk = {
walk() { console.log('Walking...'); }
};
let person = Object.assign(Object.create(canEat), canWalk);
person.eat();
person.walk();
Summary
| Concept | Purpose |
|---|---|
| Prototype | Shared methods and properties |
| Prototype chain | Lookup path for properties |
new |
Creates object with constructor’s prototype |
class |
Cleaner syntax over prototypes |
extends |
Sets up prototype chain for inheritance |
Prototype inheritance is fundamental to understanding how JavaScript objects, arrays, and built-in methods work under the hood.