One. Two prototypes
Many people know that javascript is a prototype inheritance. Each constructor has a prototype member, through which javascript inheritance can be beautiful.
In fact, this attribute alone cannot complete the inheritance of javascript.
I won't say much about the prototype we use in the code. 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 cannot be modified, because this is the basis for maintaining javascript inheritance.
The code copy is as follows:
//Constructor Statement
function Guoyansi(){ }
function GuoyansiEx(){}
//Prototype inheritance
GuoyansiEx.prototype=new Guoyansi();
//Create an object
var g1=new GuoyansiEx();
var g2=new GuoyansiEx();
The objects in the above code can be explained by the following figure
2. Prototype maintenance
An instance generated by a constructor whose constructor attribute always points to the constructor. We will think that the statement is correct for the time being.
The code copy is as follows:
function Guoyansi(){ }
var obj1=new Guoyansi();
console.log(obj1.constructor===Guoyansi);//true
In fact, the constructor itself does not have the constructor attribute, so where does this attribute come from?
The answer is: from the prototype.
Therefore, the following conclusions are drawn
The code copy is as follows: obj1.constructor===Guoyansi.prototype.constructor===Guoyansi
Since we can find the constructor through constructor, we can further improve the above diagram.
The code copy 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 false?
Now do an analysis.
The prototype of GuoyansiEx was rewritten by the instance of Guoyansi, so the constructor in the prototype of GuoyansiEx is naturally also an instance of Guoyansi.
The constructor in the Guoyansi instance comes from Guoyansi.prototype. However, Guoyansi.prototype has not been rewritten.
So the constructor of Guoyansi.prototype points to Guoyansi (constructor);
Based on the above analysis, we draw the following conclusions
The code copy is as follows: GuoyansiEx.constructor===Guoyansi.constructor===Guoyansi;
If the Constructor's directive requirements are very accurate during the development process, the following processing can be done.
The code copy is as follows:
/**Method 1:**/
function Guoyansi(){}
function GuoyansiEx(){}
GuoyansiEx.prototype=new Guoyansi();
GuoyansiEx.prototype.constructor=GuoyansiEx;//Reset constructor pointer.
The code copy is as follows:
/**
Method 2
**/
function Guoyansi(){}
function GuoyansiEx(){
this.constructor=arguments.callee;
}
GuoyansiEx.prototype=new Guoyansi();
The code copy is as follows:
/**
Method 3
**/
function Guoyansi(){}
function GuoyansiEx(){
this.constructor=GuoyansiEx;
}
GuoyansiEx.prototype=new Guoyansi();
3. What is the use of an invisible prototype?
We can operate the visible prototype chain to complete our inheritance, so we cannot see and operate this invisible prototype chain. What is the use of it?
There is a feature in object-oriented inheritance: similarity. Subclasses have similarities to parent classes. Therefore, in subclasses, you cannot use delete to delete members inherited from parent classes. That is to say, subclasses must have the characteristics of parent classes.
To maintain this feature, javascript generates an invisible prototype property inside the object and does not allow the user to access it. In this way, the user can modify the constructor for any purpose,
It will not destroy the characteristics of the child class having the parent class.
In short: internal prototypes are required by JavaScript's prototype inheritance mechanism, while external prototypes are required by users to implement inheritance.
4. __proto__ in the Firefox engine SpiderMonkey
Still this code.
The code copy 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 properties of the prototype of the parent class Guoyansi starting from obj.
This is the idea.
Step 1: 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 in many books, it says that after the constructor is modified, the level cannot find the prototype in the parent class. I don’t know what’s going on.
Enough of a more concise attribute in Firefox._proto_
By default, SpiderMonkey adds an attribute called _proto_ to any created object, which points to the prototype used by the constructor.
In fact, it is the invisible prototype chain we mentioned above, but it is just a disguised disclosure in this place.
You can access the age in this way
console.log(obj2.__proto__.__proto__.age);//24
This does indeed successfully access the prototype attribute of the parent class, but this attribute is only applicable to Firefox, and there will be errors in other browsers.
In E5, Object is extended to Object.getPrototypeOf(), and you can access all parent class prototypes.
The code copy 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's prototype"+proto);
The result is: GuoyansiEx
Guoyansi
Object
Prototype null for object
I personally think these should be considered one of the essences of object-oriented JavaScript. Please refer to it yourself and use it in your own project according to your needs.