Home >Web Front-end >JS Tutorial >Detailed explanation of javascript prototype chain maintenance and inheritance_javascript skills

Detailed explanation of javascript prototype chain maintenance and inheritance_javascript skills

WBOY
WBOYOriginal
2016-05-16 16:30:271447browse

One. Two prototypes

Many people know that JavaScript is prototypal inheritance. Each constructor has a prototype member, through which the inheritance of JavaScript can be beautifully explained.
In fact, JavaScript inheritance cannot be completed by relying on this attribute alone.
The prototype we use in the code to complete inheritance will not be discussed here. You can check the information.
Another invisible prototype member.
Each instance has a prototype attribute pointing to the prototype. This attribute cannot be accessed, and of course it cannot be modified, because this is the basis for maintaining JavaScript inheritance.

Copy code The code is as follows:

//Constructor declaration
function Guoyansi(){ }
Function GuoyansiEx(){}
//Prototypal inheritance
​​​​​ GuoyansiEx.prototype=new Guoyansi();
//Create object
      var g1=new GuoyansiEx();
      var g2=new GuoyansiEx();

The objects in the above code can be illustrated by the following diagram

2. Prototype maintenance

The constructor attribute of an instance generated by a constructor always points to the constructor. We temporarily think this is correct.

Copy code The code is as follows:

function Guoyansi(){ }
var obj1=new Guoyansi();
console.log(obj1.constructor===Guoyansi);//true

In fact, the constructor itself does not have the attribute constructor, so where does this attribute come from?
The answer is: from the prototype.
Therefore, the following conclusion is drawn

Copy code The code is as follows:
obj1.constructor===Guoyansi.prototype.constructor===Guoyansi

Since we can find the constructor through constructor, we can further improve the above diagram.

Copy code The code is as follows:

function GuoyansiEx(){}
                                GuoyansiEx.prototype=new Guoyansi();
console.log(GuoyansiEx.constructor===GuoyansiEx)//false

According to the above picture, the above result should be true, but why is it false?

Let’s do an analysis now.
The prototype of GuoyansiEx was rewritten by the instance of Guoyansi, so the constructor in the prototype of GuoyansiEx is naturally from the instance of Guoyansi.
The constructor in the Guoyansi instance comes from Guoyansi.prototype. And Guoyansi.prototype has not been rewritten,
So the constructor of Guoyansi.prototype points to Guoyansi (constructor);

Based on the above analysis, the following conclusions are drawn

Copy code The code is as follows:
GuoyansiEx.constructor===Guoyansi.constructor===Guoyansi;

If the direction of the Constructor is very precise during the development process, you can do the following.

Copy code The code is as follows:

/**Method 1:**/
function Guoyansi(){}
function GuoyansiEx(){}
                                GuoyansiEx.prototype=new Guoyansi();
                                                                                                                                      GuoyansiEx.prototype.constructor=GuoyansiEx;//Reset the constructor pointer.

Copy code The code is as follows:

/**
Method 2
            **/
function Guoyansi(){}
function GuoyansiEx(){
This.constructor=arguments.callee;
            }
​​​​​​ GuoyansiEx.prototype=new Guoyansi();

Copy code The code is as follows:

/**
Method 3
            **/
function Guoyansi(){}
function GuoyansiEx(){
This.constructor=GuoyansiEx;
            }
​​​​​​ GuoyansiEx.prototype=new Guoyansi();

3. What is the use of invisible prototypes?

We can operate the visible prototype chain to complete our inheritance, but we can neither see nor operate this invisible prototype chain. What is the use of it.
Inheritance in object-oriented has a characteristic: similarity. Subclasses have similarities with parent classes. Therefore, in subclasses, you cannot use delete to delete members inherited from parent classes. In other words, subclasses must have the characteristics of parent classes. Features.
In order to maintain this feature, JavaScript creates a prototype attribute inside the object that we cannot see and does not allow users to access it. In this way, users can modify the constructor for any purpose,
It will not destroy the characteristics of the parent class that the subclass has.
In short: the internal prototype is needed by JavaScript's prototypal inheritance mechanism, while the external prototype is needed by users to implement inheritance.

4. __proto__ in Firefox engine SpiderMonkey

Still this code.

Copy code The code is as follows:

function Guoyansi(){}
                 Guoyansi.prototype.age=24;
function GuoyansiEx(){}
            var obj1=new Guoyansi();
                           GuoyansiEx.prototype=obj1;
​​​​​​ GuoyansiEx.prototype.constructor=GuoyansiEx;//Reset constructor pointer.
            var obj2=new GuoyansiEx();

I now want to access the age of the attributes of the prototype of the parent class Guoyansi starting from obj upward.
The idea is this.
Step one: obj2====>obj2.constructor.prototype
Part 2: obj2.constructor.prototype===>GuoyansiEx.prototype;
Part 3: GuoyansiEx.prototype===>obj1;
Part 4: obj1.constructor====>Guoyansi
Part 5: Guoyansi.prototype.age

Write it like this: console.log(obj2.constructor.prototype.constructor.prototype.age)//24;
The final result is 24.
The final result is 24. It can be executed normally, but many books say that after the constructor is modified, the prototype in the parent class cannot be found. I don’t know what is going on.

Introduced a more concise property in Firefox._proto_
SpiderMonkey adds an attribute named _proto_ to any created object by default, which points to the prototype used by the constructor.
In fact, it is the invisible prototype chain we mentioned above, but it is just made public in disguise here.
You can access age
like this console.log(obj2.__proto__.__proto__.age);//24
This indeed successfully accesses the prototype attribute of the parent class, but this attribute is only applicable to Firefox and will cause errors in other browsers.
In E5, Object.getPrototypeOf() has been extended to Object, and you can access the prototypes of all parent classes.

Copy code The code is as follows:

function Guoyansi(){}
                 Guoyansi.prototype.age=24;
function GuoyansiEx(){}
            var obj1=new Guoyansi();
                           GuoyansiEx.prototype=obj1;
​​​​​​ GuoyansiEx.prototype.constructor=GuoyansiEx;//Reset constructor pointer.
            var obj2=new GuoyansiEx();
          var proto=Object.getPrototypeOf(obj2);
             while(proto){
console.log(proto.constructor);
                   proto=Object.getPrototypeOf(proto);
            }
console.log("object prototype" proto);

The result is: GuoyansiEx
Guoyansi
Object
The prototype of object is null

Personally I think these should be considered one of the essences of object-oriented JavaScript. Friends, please refer to it yourself and use it in your own projects according to your needs

Statement:
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn