Prototypes and Prototype Chain in JavaScript
Description
The prototype is the mechanism for implementing inheritance in JavaScript. Every object has a hidden property [[Prototype]] (accessible via __proto__ or Object.getPrototypeOf()), which points to its prototype object. The prototype object itself also has a prototype, forming a chain-like structure known as the prototype chain. When accessing a property of an object, if the property does not exist on the object itself, the search proceeds up the prototype chain until the property is found or the end of the chain (null) is reached.
Detailed Explanation
-
Prototype Object
- Every function automatically receives a
prototypeproperty when created, which points to a prototype object. - When a function is called as a constructor with
new, the newly created instance's[[Prototype]]will point to that function'sprototype.
Example:
function Person(name) { this.name = name; } // Add a method to the prototype object Person.prototype.sayHello = function() { console.log(`Hello, I'm ${this.name}`); }; const alice = new Person("Alice"); alice.sayHello(); // Output: Hello, I'm Alicealicedoes not have its ownsayHellomethod but finds it onPerson.prototypevia[[Prototype]].
- Every function automatically receives a
-
Formation of the Prototype Chain
- The prototype object itself is also an object, so it has a
[[Prototype]]. For example, the[[Prototype]]ofPerson.prototypepoints toObject.prototype. - The top of the chain is
Object.prototype, whose[[Prototype]]isnull.
Example:
console.log(alice.__proto__ === Person.prototype); // true console.log(alice.__proto__.__proto__ === Object.prototype); // true console.log(alice.__proto__.__proto__.__proto__); // null- When looking up a property, the order is:
alice→Person.prototype→Object.prototype→null.
- The prototype object itself is also an object, so it has a
-
Property Shadowing and Overwriting
- If an object has its own property, it will not look up the prototype chain (the property is "shadowed").
- Direct assignment only modifies the object's own property and does not affect properties on the prototype chain.
Example:
alice.sayHello = function() { console.log("Hola!"); }; alice.sayHello(); // Output: Hola! (accesses own property) const bob = new Person("Bob"); bob.sayHello(); // Output: Hello, I'm Bob (still accesses the method on the prototype) -
Prototype Chain and Inheritance
- Inheritance can be achieved by setting the child class's prototype to an instance of the parent class:
function Student(name, grade) { Person.call(this, name); // Call the parent constructor this.grade = grade; } Student.prototype = Object.create(Person.prototype); // Inherit the prototype Student.prototype.constructor = Student; // Fix constructor reference Student.prototype.study = function() { console.log(`${this.name} is studying.`); }; const charlie = new Student("Charlie", 5); charlie.sayHello(); // Inherited from Person.prototype- The prototype chain is now:
charlie→Student.prototype(i.e., an instance ofPerson) →Person.prototype→Object.prototype.
Summary
The prototype chain is a core feature of JavaScript, enabling property and method sharing through the [[Prototype]] links of objects. Understanding the prototype chain is essential for mastering inheritance, property lookup mechanisms, and avoiding common property shadowing issues.