Home >Web Front-end >JS Tutorial >Deep Dive into Prototypes: The Backbone of JavaScript
Prototypes are a core concept in JavaScript, forming the foundation of its object-oriented programming (OOP) capabilities. While other languages use classes as the basis for inheritance, JavaScript relies on prototypes. In this article, we’ll explore prototypes in depth and uncover how they power inheritance, object behavior, and more in JavaScript.
In JavaScript, every object has an internal property called [[Prototype]] that points to another object. This is the prototype of the object, and it acts as a fallback mechanism for properties or methods that are not found directly on the object.
The prototype chain is a series of linked prototypes. If a property or method isn't found on an object, JavaScript looks up the chain until it reaches null.
const parent = { greet: () => console.log("Hello from parent!") }; const child = Object.create(parent); child.greet(); // Output: "Hello from parent!" console.log(child.hasOwnProperty('greet')); // Output: false
Here, child doesn't have a greet method, so JavaScript looks up the prototype chain to parent and finds it there.
JavaScript provides two different terms related to prototypes that can be confusing:
__proto__:
prototype:
Example:
function Person(name) { this.name = name; } Person.prototype.sayHello = function () { console.log(`Hello, my name is ${this.name}`); }; const alice = new Person("Alice"); console.log(alice.__proto__ === Person.prototype); // true alice.sayHello(); // Output: "Hello, my name is Alice"
JavaScript’s inheritance is prototype-based, meaning objects inherit directly from other objects rather than classes.
Creating Inheritance
const animal = { eat() { console.log("Eating..."); } }; const dog = Object.create(animal); dog.bark = function () { console.log("Barking..."); }; dog.eat(); // Output: "Eating..." dog.bark(); // Output: "Barking..."
The dog object inherits the eat method from the animal object.
The Object.create method creates a new object with a specified prototype. It's a cleaner and more intuitive way to set up inheritance.
Example:
const person = { introduce() { console.log(`Hi, I'm ${this.name}`); } }; const student = Object.create(person); student.name = "John"; student.introduce(); // Output: "Hi, I'm John"
While extending built-in prototypes like Array or Object is possible, it’s generally discouraged as it can lead to conflicts.
Example:
Array.prototype.last = function () { return this[this.length - 1]; }; console.log([1, 2, 3].last()); // Output: 3
Why Avoid It?
With ES6, JavaScript introduced class syntax, providing a more familiar OOP experience. However, under the hood, classes still use prototypes.
Example:
const parent = { greet: () => console.log("Hello from parent!") }; const child = Object.create(parent); child.greet(); // Output: "Hello from parent!" console.log(child.hasOwnProperty('greet')); // Output: false
Even with class, the inheritance is prototype-based.
Prototype-based inheritance is more memory-efficient because methods are shared across instances rather than being duplicated.
Example:
function Person(name) { this.name = name; } Person.prototype.sayHello = function () { console.log(`Hello, my name is ${this.name}`); }; const alice = new Person("Alice"); console.log(alice.__proto__ === Person.prototype); // true alice.sayHello(); // Output: "Hello, my name is Alice"
Here, drive is not duplicated for each car; instead, both instances share the same method.
Understanding prototypes is essential for mastering JavaScript. While ES6 classes have made object-oriented programming in JavaScript more approachable, the prototype system remains at the core of the language. By diving deep into prototypes, you unlock the ability to write efficient, scalable, and maintainable code.
The above is the detailed content of Deep Dive into Prototypes: The Backbone of JavaScript. For more information, please follow other related articles on the PHP Chinese website!