How much do you know about the Prototype Chain?
The prototype chain is one of the core features of JavaScript, and certainly one of its challenges. Developers coming from other object-oriented programming languages may find JavaScript somewhat confusing. Although JavaScript can be considered an object-oriented language, it implements object-oriented programming through a prototype-based mechanism rather than a class-based mechanism. It lacks traditional inheritance and polymorphism found in other OOP languages, but we can achieve inheritance through prototypes.
Below, I'll guide you through understanding the prototype chain.
First Contact with Prototype Chains
Previously, I wrote an article titled "Do You Understand JavaScript Closures?", which introduced closures by starting with their name to infer the concepts involved. Similarly, let's begin our discussion of prototype chains by breaking down the term itself.
The term "prototype chain" can be divided into two parts: "prototype" and "chain".
The "Chain"
In JavaScript, we can visualize a top-down chain structure. Consider this example:
Example 1
function func(){
this.a = '1';
this.b = '2';
}
func.prototype.b='3';
func.prototype.c='4';
var f = new func();
console.log(f.a);
console.log(f.b);
console.log(f.c);
The relationships between properties in this example can be visualized as follows:
Figure 1
This chain structure first looks at the func() instance object. If the desired property isn't found, it then searches the prototype (prototype). In our example: f.a exists in the object f, so it directly outputs 1; f.c isn't found in f, so it searches the prototype and outputs 4; for f.b, both the object and prototype have this property, but the object's property takes priority, so it outputs 2. This demonstrates JavaScript's prototype chain lookup mechanism.
You might wonder about the "wasted" b property in the prototype. We'll explain its usage later.
The "Prototype"
The prototype (prototype) refers to the template object from which other objects inherit properties. In classical OOP terms, we might compare prototypes to static properties that belong to the class rather than instances, but remain accessible to instances.
In our example, we can write func.prototype.c = '4' but not f.prototype.c = '4' - the latter would throw an error because f.prototype is undefined. The prototype is a property of the constructor function, not of instances.
Prototype Chain
Combining these concepts, let's examine how prototype chains work through an extended example:
Example 2
function func(){
this.a = '1';
this.b = '2';
}
func.prototype.b = '3';
func.prototype.c = '4';
var f = new func();
function func2(){
this.d = '5';
}
func2.prototype = Object.create(func.prototype);
func2.prototype.c = '6';
var f2 =new func2();
console.log(f.a);
console.log(f2.b);
console.log(f2.d);
console.log(f2.c);
console.log(f.c);
Visual representation:
Figure 2
Following the lookup order: f.a is 1; f2.b isn't found in f2 or func2.prototype, so it finds 3 in func.prototype; f2.d is 5; f2.c finds 6 in func2.prototype before reaching func.prototype; f.c remains 4 as it directly accesses func.prototype. This demonstrates prototype chain inheritance without affecting parent prototypes.
Practical Applications
We can use prototype chains to simulate classical inheritance:
Example 3
function Action(){
this.pro1 = 'a';
}
Action.prototype = {
pro2:'b',
operate:function(){
console.log('action');
}
}
function IndexAction(){
this.pro1 = 'b';
}
IndexAction.prototype = Object.create(Action.prototype);
var index = new IndexAction();
index.operate();
Here, IndexAction inherits pro2 and operate() from Action's prototype, while maintaining its own pro1 property. This demonstrates prototype-based inheritance.
Performance Considerations
Prototype chain lookups can impact performance when dealing with deep chains or non-existent properties. It's crucial to understand your prototype chain structure and keep it reasonably short. Avoid extending native object prototypes (like Object.prototype) unless for polyfilling purposes.
For example, avoid:
Object.prototype = {
pro:"pro",
operate:function(){}
}
In conclusion, true understanding of prototype chains comes through practical implementation. Regular practice with prototype-based programming will help solidify these concepts.
For reprinting, please send an email to 1244347461@qq.com for approval. After obtaining the author's consent, kindly include the source as a link.
Related Articles
Do you understand JavaScript closures?
Publish Date:2025/02/21 Views:108 Category:JavaScript
-
The function of a closure can be inferred from its name, suggesting that it is related to the concept of scope. A closure itself is a core concept in JavaScript, and being a core concept, it is naturally also a difficult one.
Do you know about the hidden traps in variables in JavaScript?
Publish Date:2025/02/21 Views:178 Category:JavaScript
-
Whether you're just starting to learn JavaScript or have been using it for a long time, I believe you'll encounter some traps related to JavaScript variable scope. The goal is to identify these traps before you fall into them, in order to av
如何在 JavaScript 中合并两个数组而不出现重复的情况
Publish Date:2024/03/23 Views:86 Category:JavaScript
-
本教程介绍了如何在 JavaScript 中合并两个数组,以及如何删除任何重复的数组。
如何检查 JavaScript 中的变量是否为字符串
Publish Date:2024/03/23 Views:158 Category:JavaScript
-
本教程介绍了如何在 JavaScript 中检查变量是否为字符串。
在 JavaScript 中扁平化一个数组
Publish Date:2024/03/23 Views:113 Category:JavaScript
-
本教程介绍了如何在 JavaScript 中扁平化一个数组。
在 JavaScript 中将浮点数转换为整数
Publish Date:2024/03/23 Views:72 Category:JavaScript
-
本教程列出了在 JavaScript 中将浮点数转换为整数的各种方法。
JavaScript POST
Publish Date:2024/03/23 Views:96 Category:JavaScript
-
本教程讲解如何在不使用 JavaScript 表单的情况下发送 POST 数据。
JavaScript 斐波那契
Publish Date:2024/03/23 Views:161 Category:JavaScript
-
我们可以使用 JavaScript 中的循环生成斐波那契数列。