In JavaScript, objects do not have prototypes, but constructors have prototypes
. The meaning of prototype is: if the constructor has a prototype object A, then the instances created by the constructor must be copied from A
/*Declare 2 constructors*/
var flower=function(){
this.name="nokia";
}
var flower2=function(){
this.age=22;
}
/*Prototype chain*/
flower2. prototype=new flower();
/*According to the definition of prototype just now, instance obj must be copied from new flower();*/
obj=new flowe2();
/*Inherited from the parent class Properties*/
alert(obj.name); //==>"nokia"
alert(obj.age); //==>22
A construct The constructor attribute of the instance generated by the constructor always points to the constructor by default
alert(obj.constructor);//==>flower
The constructor attribute of the constructor prototype points to the constructor itself
alert( flower.prototype.constructor==flower);//==>true
Constructor will conflict with prototype inheritance
function flower(){}
function flower2(){}
flower2.prototype=new flower();
var obj1=new flower();
var obj2=new flower2();
/*The problem arises, the constructor attributes of both instances point to flower*/
alert(obj1.constructor==obj2.constructor);
/*obj1 and obj2 are instances generated by different constructors, pointing to the same constructor, obviously there is a problem*/
Solution
flower2.prototype=new flower();
/*After resetting the prototype, modify Prototype's constructor property*/
flower2.prototype.constructor=flower2
or override the constructor property every time you construct an instance
function flower2(){
this.constructor=arguments.callee;
}
flower2.prototype=new flower();
In addition, prototypal inheritance does not provide a method to call the parent class
However, we are based on prototypal inheritance and record the parent class through static variables. To make up for this flaw
var Class={
create :function()
{
var _class=function()
{
this.init.apply(this,arguments);
}
_class.prototype.init=Function. prototype.init;
try{
return _class;
}finally{
_class=null;
}
}
};
//Default constructor
Function.prototype.init=function(){}
//Method extension
Function.prototype.extend=function(list)
{
for(var i in list)this.prototype [i]=list[i];
return this;
}
//Multi-level inheritance
Function.prototype.inherits=function(parent)
{
//Inheritance Depth level
var _depth=0;
//Method attribute transplantation
this.extend(new parent());
//Inheritance of initialization constructor class usually does not inherit the constructor
this.prototype.init=Function.prototype.init;
//Static parent class of the class
this.parent=parent;
//Execute the parent class function
this.prototype.parent= function(name)
{
//If there are no parameters, execute the constructor
if(!name)name='init';
//The parent class to be executed
var _parent= parent;
//If it is currently executed in the parent class, continue to look up the super class
if(_depth)
{
for(var i=0;i<_depth;i )
{
_parent=_parent.parent;
}
}
//Set the level
_depth;
try{
//Execute the function and return the value
return _parent.prototype[name].apply(this,Array.prototype.slice.apply(arguments,[1]));
}catch(e){
throw(e);
}finally {
//Recovery level
_depth--;
}
}
return this;
}
Example:
//Create a constructor named class1
var class1=Class.create ().extend({
b:function()
{
alert('clas');
alert(this.c);
},
c:100
});
//Create an instance of "object" (constructor)
var s=new class1();
s.b();// ==>"clas",100
Inherit the parent class and call the method of the parent class:
var test=Class.create().inherits(class1).extend({
b:function()
{
alert('test');
this.parent('b')
},
c:110
});