Let's discuss the role of constructor. For more information, see. Extracted from 51js.
The Code is as follows:
Script Function. prototype. createInstance = function (){
Var T = function (){};
T. prototype = this. prototype;
T. constructor = this;
Var o = new T ();
This. apply (o, arguments );
Return o;
} Script
Let's talk about the phrase T. constructor = this in the above Code. I feel that this sentence has no practical effect,
Itself T. constructor should be Funtion. Why should we set it as a Funtion instance,
The Code is as follows:
Script
Function. prototype. $ extends = function (p ){
This. $ super = p;
Var fn = function (){};
Fn. prototype = p. prototype;
This. prototype = new fn ();
// This sentence is added by myself. Make sure that the constructor that constructs the subclass instance still points to the constructor function of the subclass.
This. prototype. constructor = this;
//-----------------------------
Return this;
};
Function Animal (){
}
Function Cat (){
}
Cat. $ extends (Animal );
Var bb = new Cat ();
Alert (bb. constructor );
// However, this (this. prototype. constructor = this) method cannot be used to restore the Animal prototype through the bb object.
// The following statement still returns the Cat function, not the Animal
Alert (bb. constructor. prototype. constructor)
Script
In the above code, I added one sentence, corrected that the subclass constructor still points to the subclass function, but the back-to-back of the prototype chain of the object cannot reach the parent class prototype. The solution is:
Remove this. prototype. constructor = this; do not set the constructor attribute for the prototype, but set a constructor attribute for the instance. The following code
The Code is as follows:
Script
Function. prototype. $ extends = function (p ){
This. $ super = p;
Var fn = function (){};
Fn. prototype = p. prototype;
This. prototype = new fn ();
Return this;
};
Function Animal (){
}
Function Cat (){
This. constructor = arguments. callee;
}
Cat. $ extends (Animal );
Var bb = new Cat ();
Alert (bb. constructor );
// This method can be used to return the bb object to the Animal prototype.
Alert (bb. constructor. prototype. constructor)
Script
Finally, the actual functions of constructor are analyzed.
The Code is as follows:
Script
// Define a function
Var f = function (){
}
// True is displayed here, because the f constructor is Funtion, and the prototype attribute _ proto _ in f is assigned as the prototype of the constructor, that is, Function prototype.
// Instanceof checks whether the _ proto _ in f has a common node with Function. prototype. If yes, true is returned.
Alert (f instanceof Function)
// Obj is an instance of f.
Var obj = new f;
// The prototype attribute _ proto _ inside obj is assigned to f. prototype when new f is used. Obviously, f. prototype and Function. prototype have no common nodes, so false is displayed.
Alert (obj instanceof Function)
// In order to make obj an instance of Function (obj instanceof Function) display true
// Only f. prototype = Function. prototype is required
F. prototype = Function. prototype;
// However, I do not recommend this method because. modifications to prototype damage the Function. prototype, such as f. prototype. name = "51js" adds a name attribute to the Function prototype.
// The correct method should be as follows, so that modifications such as f. prototype. name won't destroy the Function prototype.
F. prototype = new Function ();
F. prototype. name = "zhouyang ";
/** The key here is to re-adjust the constructor attribute to f and maintain the constructor to ensure that obj can correctly restore the prototype chain,
* If we want to obtain the prototype chain inside obj, but only know obj, we do not know how obj is instantiated, because the _ proto _ attribute inside obj is invisible, we need to obtain the internal source of obj only through obj. constructor to obtain the constructor, and then obtain the prototype of the constructor.
* 1. If we add the following sentence (f. prototype. constructor = f ),
* Only the prototype chain (obj) at Layer 1 can be retrieved. constructor. prototype (subclass prototype) --> obj. constructor. prototype. constructor. prototype (still a subclass prototype). In this way, you can only repeat the first-layer prototype chain.
**/
F. prototype. constructor = f;
Obj = new f;
Alert ("found subclass ---" + obj. constructor + "\ n"
+ "The Child class is found, and the parent class cannot be found ---" + obj. constructor. prototype. constructor)
Alert (obj instanceof Function)
/** 2. If we use the following method to set the constructor of the f instance in the f definition, rather than the constructor of the f prototype
* You can refer to the 2-layer prototype chain, that is, obj. constructor. prototype (subclass prototype) --> obj. constructor. prototype. constructor. prototype (parent class prototype)
* Obviously, this situation is in line with the prototype inheritance chain of the object.
*/
F = function (){
This. constructor = arguments. callee;
}
F. prototype = new Function ();
F. prototype. name = "zhouyang ";
Obj = new f;
Alert ("found subclass ---" + obj. constructor + "\ n"
+ "Find the parent class ---" + obj. constructor. prototype. constructor)
Alert (obj instanceof Function)
Script
The Code is as follows:
Script
// Define a function
Var f = function (){
}
// True is displayed here, because the f constructor is Funtion, and the prototype attribute _ proto _ in f is assigned as the prototype of the constructor, that is, Function prototype.
// Instanceof checks whether the _ proto _ in f has a common node with Function. prototype. If yes, true is returned.
Alert (f instanceof Function)
// Obj is an instance of f.
Var obj = new f;
// The prototype attribute _ proto _ inside obj is assigned to f. prototype when new f is used. Obviously, f. prototype and Function. prototype have no common nodes, so false is displayed.
Alert (obj instanceof Function)
// In order to make obj an instance of Function (obj instanceof Function) display true
// Only f. prototype = Function. prototype is required
F. prototype = Function. prototype;
// However, I do not recommend this method because. modifications to prototype damage the Function. prototype, such as f. prototype. name = "51js" adds a name attribute to the Function prototype.
// The correct method should be as follows, so that modifications such as f. prototype. name won't destroy the Function prototype.
F. prototype = new Function ();
F. prototype. name = "zhouyang ";
/** The key here is to re-adjust the constructor attribute to f and maintain the constructor to ensure that obj can correctly restore the prototype chain,
* If we want to obtain the prototype chain inside obj, but only know obj, we do not know how obj is instantiated, because the _ proto _ attribute inside obj is invisible, we need to obtain the internal source of obj only through obj. constructor to obtain the constructor, and then obtain the prototype of the constructor.
* 1. If we add the following sentence (f. prototype. constructor = f ),
* Only the prototype chain (obj) at Layer 1 can be retrieved. constructor. prototype (subclass prototype) --> obj. constructor. prototype. constructor. prototype (still a subclass prototype). In this way, you can only repeat the first-layer prototype chain.
**/
F. prototype. constructor = f;
Obj = new f;
Alert ("found subclass ---" + obj. constructor + "\ n"
+ "The Child class is found, and the parent class cannot be found ---" + obj. constructor. prototype. constructor)
Alert (obj instanceof Function)
/** 2. If we use the following method to set the constructor of the f instance in the f definition, rather than the constructor of the f prototype
* You can refer to the 2-layer prototype chain, that is, obj. constructor. prototype (subclass prototype) --> obj. constructor. prototype. constructor. prototype (parent class prototype)
* Obviously, this situation is in line with the prototype inheritance chain of the object.
*/
F = function (){
This. constructor = arguments. callee;
}
F. prototype = new Function ();
F. prototype. name = "zhouyang ";
Obj = new f;
Alert ("found subclass ---" + obj. constructor + "\ n"
+ "Find the parent class ---" + obj. constructor. prototype. constructor)
Alert (obj instanceof Function)
Script conclusion constructor is used to maintain the prototype chain of objects.
I 'd like to tell guoguo and winter whether it is correct or not. In addition, I think what prototype pollution usually refers ??
Which can be explained below?
The Code is as follows:
Script
Var f = function (x ){}
F. prototype = {};
Alert (new f). constructor );
F. prototype. constructor = f;
Alert (new f). constructor );
Script