


In-depth understanding of JavaScript series (6) Powerful prototype and prototype chain_javascript skills
Preface
JavaScript does not contain a traditional class inheritance model, but uses a prototypal prototype model.
Although this is often mentioned as a shortcoming of JavaScript, the prototype-based inheritance model is actually more powerful than traditional class inheritance. Implementing the traditional class inheritance model is easy, but implementing prototypal inheritance in JavaScript is much more difficult.
Since JavaScript is the only widely used language based on prototypal inheritance, it takes some time to understand the difference between the two inheritance models. Today we will learn about prototypes and prototype chains.
Prototype
10 years ago, when I first learned JavaScript, I usually wrote code in the following way:
var decimalDigits = 2,
tax = 5;
function add(x, y) {
return x y ;
}
function subtract(x, y) {
return x - y;
}
//alert(add(1, 3));
Get the results by executing each function. After learning the prototype, we can use the following methods to beautify the code.
Prototype usage method 1:
Before using the prototype, we need to make small modifications to the code:
var Calculator = function (decimalDigits, tax) {
this.decimalDigits = decimalDigits;
this.tax = tax;
};
Then, set the prototype of the Calculator object by assigning an object literal to the prototype property of the Calculator object.
Calculator.prototype = {
add: function ( x, y) {
return x y;
},
subtract: function (x, y) {
return x - y;
}
};
//alert((new Calculator()).add(1, 3));
In this way, we can call the add method to calculate the result after new Calculator object.
Prototype usage method 2:
The second method is to use an expression that the function will execute immediately when assigning the prototype prototype, which is the following format:
Calculator.prototype = function () { } ();
Its advantage is already known in the previous post, that is, it can encapsulate private functions and expose simple usage names in the form of return to achieve public/private effects. Modify The final code is as follows:
Calculator.prototype = function () {
add = function (x, y) {
return x y;
},
subtract = function (x, y) {
return x - y;
}
return {
add: add,
subtract: subtract
}
} ();
//alert((new Calculator()).add(11 , 3));
In the same way, we can create a new Calculator object and later call the add method to calculate the result.
One more point
Step-by-step statement:
When using the prototype above, there is a limitation that the prototype object is set at once. Let’s talk about how to set each attribute of the prototype separately.
var BaseCalculator = function () {
// Declare a decimal digit for each instance
this.decimalDigits = 2;
};
//Use the prototype to extend 2 object methods for BaseCalculator
BaseCalculator.prototype.add = function (x, y) {
return x y;
};
BaseCalculator.prototype.subtract = function (x, y) {
return x - y;
};
First, declare a BaseCalculator object. In the constructor, a decimal number attribute decimalDigits will be initialized, and then two functions are set through the prototype attribute, namely add(x,y) and subtract( x, y), of course you can also use any of the two methods mentioned above. Our main purpose is to see how to set the BaseCalculator object to the prototype of the real Calculator.
var BaseCalculator = function() {
this. decimalDigits = 2;
};
BaseCalculator.prototype = {
add: function(x, y) {
return x y;
},
subtract: function( x, y) {
return x - y;
}
};
After creating the above code, let’s start:
var Calculator = function () {
//Declare a tax number for each instance
this.tax = 5;
};
Calculator.prototype = new BaseCalculator() ;
We can see that the prototype of Calculator points to an instance of BaseCalculator, in order to allow Calculator to integrate its two functions: add(x,y) and subtract(x,y) , and one more thing to say is that since its prototype is an instance of BaseCalculator, no matter how many Calculator object instances you create, their prototypes point to the same instance.
var calc = new Calculator();
alert (calc.add(1, 1));
//The decimalDigits attribute declared in BaseCalculator can be accessed in Calculator
alert(calc.decimalDigits);
After running the above code, we can see that because the prototype of Calculator points to the instance of BaseCalculator, its decimalDigits attribute value can be accessed. If I don't want Calculator to access the attribute value declared in the constructor of BaseCalculator, then What to do? Do this:
var Calculator = function () {
this.tax= 5;
};
Calculator.prototype = BaseCalculator.prototype;
By assigning the prototype of BaseCalculator to the prototype of Calculator, so that you are in Calculator The decimalDigits value cannot be accessed on the instance. If you access the following code, an error will occur.
var calc = new Calculator();
alert (calc.add(1, 1));
alert(calc.decimalDigits);
Rewrite the prototype:
When using third-party JS libraries, sometimes The prototype methods they defined cannot meet our needs, but they are inseparable from this class library, so at this time we need to rewrite one or more properties or functions in their prototypes. We can continue to declare the same The form of add code is to overwrite and rewrite the previous add function. The code is as follows:
//Override the previous Calculator’s add() function
Calculator.prototype.add = function (x, y) {
return x y this.tax;
};
var calc = new Calculator();
alert(calc.add(1, 1));
In this way, the result we calculated will have one more tax than the original one value, but there is one thing to note: the rewritten code needs to be placed at the end so that it can overwrite the previous code.
Prototype chain
Before chaining the prototype, we first put a piece of code:
function Foo() {
this.value = 42;
}
Foo.prototype = {
method: function() {}
};
function Bar() {}
// Set the prototype attribute of Bar to the instance object of Foo
Bar.prototype = new Foo();
Bar.prototype .foo = 'Hello World';
// Correct Bar.prototype.constructor to Bar itself
Bar.prototype.constructor = Bar;
var test = new Bar() / / Create a new instance of Bar
// Prototype chain
test [Instance of Bar]
Bar.prototype [Instance of Foo]
{ foo: 'Hello World' }
Foo.prototype
{method: ...};
Object.prototype
{toString: ... /* etc. */};
In the above example, the test object inherits from Bar.prototype and Foo.prototype; therefore, it can access Foo’s prototype method method. At the same time, it can also access the Foo instance property value defined on the prototype. Note that new Bar() does not create a new Foo instance, but reuses the one on its prototype; therefore, all Bar instances will share the same value property.
Property lookup:
When looking for a property of an object, JavaScript will traverse the prototype chain upwards until it finds a property with a given name, until the search reaches the top of the prototype chain - that is, Object.prototype - But if the specified attribute is still not found, undefined will be returned. Let’s look at an example:
function foo() {
this.add = function (x, y) {
return x y;
}
}
foo.prototype. add = function (x, y) {
return x y 10;
}
Object.prototype.subtract = function (x, y) {
return x - y;
}
var f = new foo();
alert(f.add(1, 2)); //The result is 3, not 13
alert(f.subtract(1, 2)); //The result is -1
By running the code, we find that subtract installs what we call upward search to get the result, but the add method is a little different, which is what I think What I emphasize is that when searching for attributes, they first search for their own attributes. If there is no prototype, then search for the prototype. If there is no more, then go up and insert it into the prototype of Object. So in a certain level, use the for in statement. When traversing properties, efficiency is also an issue.
Another thing we need to note is that we can assign any type of object to the prototype, but we cannot assign atomic type values. For example, the following code is invalid:
function Foo() {}
Foo.prototype = 1; // Invalid
hasOwnProperty function:
hasOwnProperty is a method of Object.prototype. It is a good thing. It can determine whether an object contains custom properties instead of properties on the prototype chain, because hasOwnProperty is in JavaScript. The only function that handles properties without looking up the prototype chain.
// Modify Object.prototype
Object.prototype .bar = 1;
var foo = {goo: undefined};
foo.bar; // 1
'bar' in foo; // true
foo. hasOwnProperty('bar'); // false
foo.hasOwnProperty('goo'); // true
Only hasOwnProperty can give the correct and expected results when traversing the object properties can be useful. There is no other way to exclude properties on the prototype chain than properties defined on the object itself.
But there is a disgusting thing: JavaScript does not protect hasOwnProperty from being illegally occupied, so if an object happens to have this property, you need to use an external hasOwnProperty function to get the correct result.
var foo = {
hasOwnProperty: function() {
return false;
},
bar: 'Here be dragons'
};
foo.hasOwnProperty('bar'); // always returns false
// Use the hasOwnProperty of the {} object and set its top and bottom to foo
{}.hasOwnProperty.call(foo, 'bar'); // true
hasOwnProperty is the only method available when checking whether a property exists on an object. At the same time, when using for in loop to traverse objects, it is recommended to always use the hasOwnProperty method, which will avoid interference caused by prototype object expansion. Let’s take a look at an example:
// Modify Object.prototype
Object.prototype.bar = 1;
var foo = { moo: 2};
for(var i in foo) {
console.log(i); // Output two attributes: bar and moo
}
us There is no way to change the behavior of the for in statement, so if you want to filter the results, you can only use the hasOwnProperty method. The code is as follows:
// The foo variable is the one in the above example
for(var i in foo) {
if (foo.hasOwnProperty(i)) {
console.log(i);
}
}
This version of the code is the only correct way to write it. Since we used hasOwnProperty, only moo is output this time. If hasOwnProperty is not used, this code may break when native object prototypes (such as Object.prototype) are extended.
Summary: It is recommended to use hasOwnProperty, do not make any assumptions about the environment in which the code runs, and do not assume whether the native object has been extended.
Summary
Prototypes have greatly enriched our development code, but we must pay attention to some of the precautions mentioned above during daily use.

Hot AI Tools

Undresser.AI Undress
AI-powered app for creating realistic nude photos

AI Clothes Remover
Online AI tool for removing clothes from photos.

Undress AI Tool
Undress images for free

Clothoff.io
AI clothes remover

AI Hentai Generator
Generate AI Hentai for free.

Hot Article

Hot Tools

Notepad++7.3.1
Easy-to-use and free code editor

SublimeText3 Chinese version
Chinese version, very easy to use

Zend Studio 13.0.1
Powerful PHP integrated development environment

Dreamweaver CS6
Visual web development tools

SublimeText3 Mac version
God-level code editing software (SublimeText3)

Hot Topics

Introducing the new map of Genshin Impact version 4.4. Friends, Genshin Impact 4.4 version also ushered in the Sea Lantern Festival in Liyue. At the same time, a new map area will be launched in version 4.4 called Shen Yu Valley. According to the information provided, Shen Yugu is actually part of Qiaoying Village, but players are more accustomed to calling it Shen Yugu. Now let me introduce the new map to you. Introduction to the new map of Genshin Impact version 4.4. Version 4.4 will open "Chenyu Valley·Shanggu", "Chenyu Valley·Nanling" and "Laixin Mountain" in the north of Liyue. Teleportation anchor points have been opened for travelers in "Chenyu Valley·Shanggu" . ※After completing the prologue of the Demon God Quest·Act 3: The Dragon and the Song of Freedom, the teleportation anchor point will be automatically unlocked. 2. Qiaoyingzhuang When the warm spring breeze once again caressed the mountains and fields of Chenyu, the fragrant

Scope chain and prototype chain are two important concepts in JavaScript, corresponding to the two core features of scope and inheritance respectively: 1. Scope chain is a mechanism used to manage variable access and scope in JavaScript. It is formed by It is determined by the execution context and lexical scope in which the function is created; 2. The prototype chain is a mechanism for implementing inheritance in JavaScript. Based on the prototype relationship between objects, when accessing the properties or methods of an object, if the object itself does not Definition, will be searched up along the prototype chain.

Prototype, an object in js, is used to define the properties and methods of other objects. Each constructor has a prototype attribute. This attribute is a pointer pointing to a prototype object. When a new object is created, the new object will be The prototype attribute of its constructor inherits properties and methods. Prototype chain, when trying to access the properties of an object, js will first check whether the object has this property. If not, then js will turn to the prototype of the object. If the prototype object does not have this property, it will continue to look for the prototype of the prototype.

Go language and Python are two very popular programming languages, both with their own advantages and characteristics. There are also some differences between the two when it comes to high-performance programming. This article will compare the Go language and Python to explore which one is more suitable for high-performance programming. First, let us understand the Go language. The Go language is an open source programming language developed by Google that focuses on simplicity, efficiency, and concurrency. One of the design goals of the Go language is to provide a high-performance programming experience. It has lightweight coroutines (goro

The difference between prototype and prototype chain is: 1. Prototype is an attribute that each object has, including some shared attributes and methods, which is used to realize the sharing and inheritance of attributes and methods between objects, while prototype chain is a The inheritance mechanism is implemented through the prototype relationship between objects, which defines the inheritance relationship between objects so that objects can share the properties and methods of the prototype object; 2. The function of the prototype is to define the shared properties and methods of the object, so that multiple Objects can share the properties and methods of the same prototype object, and the function of the prototype chain is to realize the inheritance relationship between objects, etc.

In today's era of rapid technological advancement, the choice of programming language has become very critical. With the continuous development of the software development field, Go language and Python have become two programming languages that have attracted much attention. This article will conduct a comparative analysis of Go language and Python to help readers choose the appropriate programming language according to project needs. First, let us understand the Go language. Go language is a statically compiled programming language developed by Google. It has powerful concurrent processing capabilities and efficient garbage collection mechanism, which is very

In the past year, with the widespread application of large model technology, we have witnessed how AI has profoundly changed the way we work. In the field of programming, the intervention of AI will also bring unprecedented convenience to programmers. Recently, Feishen Technology launched FittenCode, an AI code assistant based on a large self-developed code model. It can help programmers complete coding tasks more quickly, accurately, and with higher quality, greatly improve coding efficiency, and contribute to Free and open to users! The product’s official website address: https://code.fittentech.com/FittenCode has quickly become popular since its last release. The development team worked around the clock to bring features,

The function of js prototype and prototype chain is to realize the inheritance of objects, save memory space, and improve the performance and maintainability of the code. Detailed introduction: 1. Implement the inheritance of objects. The prototype and prototype chain allow you to create an object and inherit the properties and methods of another object. When you create a new object, you can point its prototype to another object, so that the new object The object can access the properties and methods on the prototype object; 2. Save memory and improve performance. In JavaScript, each object has a prototype. Through the prototype chain, objects can share prototypes, etc.
