Prototypes and Inheritance
Prototypes
In JavaScript, prototypes are a fundamental mechanism for object inheritance. Every object has a prototype, which is another object that it inherits properties and methods from. When you try to access a property or method on an object, JavaScript first checks if the property exists on the object itself. If not, it looks up the prototype chain (more on this below).
- Prototype of an object: Every object has an internal property
[[Prototype]]
(accessed via__proto__
orObject.getPrototypeOf()
), which points to another object. - Constructor functions and prototypes: Functions in JavaScript automatically have a
prototype
property, which is an object. This object contains properties and methods that are shared by all instances created by that constructor function.
function Person(name, age) {
this.name = name;
this.age = age;
}
Person.prototype.sayHello = function () {
console.log(`Hello, my name is ${this.name}`);
};
const person1 = new Person("Alice", 30);
person1.sayHello(); // Outputs: Hello, my name is Alice
Prototypal Inheritance
Prototypal inheritance refers to the way objects can inherit properties and methods from other objects through the prototype chain. When a property or method is accessed on an object, JavaScript first checks if it's defined on the object itself. If not, it checks the prototype of that object, and so on up the prototype chain.
const animal = {
eat: function () {
console.log("Eating...");
},
};
const dog = Object.create(animal);
dog.bark = function () {
console.log("Woof!");
};
dog.eat(); // Inherited from animal, Outputs: Eating...
dog.bark(); // Outputs: Woof!
Prototype Chain
The prototype chain is a series of links between an object and its prototype. Every object in JavaScript is linked to another object via its prototype, and this chain can continue indefinitely, although in most cases it ends with Object.prototype
.
Object.prototype
is the root of all JavaScript objects, and it does not have a prototype.- If a property or method is not found in an object's prototype, the search continues up the chain until
Object.prototype
is reached.
const obj = { name: "John" };
console.log(obj.toString()); // toString is inherited from Object.prototype
Factory Functions
A factory function is a function that creates and returns an object. This pattern allows you to create multiple objects with the same properties and methods without using the new
keyword or constructor functions.
Factory functions can be used to simulate classical inheritance by setting up prototype chains manually.
function createPerson(name, age) {
return {
name,
age,
sayHello() {
console.log(`Hello, my name is ${this.name}`);
},
};
}
const person1 = createPerson("Alice", 30);
person1.sayHello(); // Outputs: Hello, my name is Alice
new
Keyword
The new
keyword is used to create instances of a constructor function. When you use new
, it does the following:
- Creates a new empty object.
- Sets the prototype of the new object to the constructor function’s
prototype
property. - Binds
this
inside the constructor function to the new object. - Returns the new object (unless the constructor explicitly returns something else).
function Person(name, age) {
this.name = name;
this.age = age;
}
const person1 = new Person("Alice", 30);
console.log(person1.name); // Alice