CopyCode The Code is as follows:/* Based on Alex Arnell's inheritance implementation .*/
VaR class = (function (){
// Temporarily store the prototype of the parent
Function subclass (){};
// Create a class
Function create (){
VaR parent = NULL, properties = $ A (arguments );
// Check whether a parent object is specified when a new class is created
// If the parent class is specified, assign the value to the parent
If (object. isfunction (properties [0])
Parent = properties. Shift ();
// Actually used as the returned class. When creating an instance, the initialize method will be called for initialization.
Function Klass (){
This. Initialize. Apply (this, arguments );
}
// Add the addmethods method to Klass after calling the create Method
// You can still call the addmethods method to expand the class-level method.
Object. Extend (Klass, class. Methods );
// Add two attributes to the returned class: superclass: parent class, subclasses: collection of child classes
Klass. superclass = parent;
Klass. subclasses = [];
// If a parent object is specified during class creation, the Klass prototype is directed to the instance of the parent object to implement prototype chain inheritance.
If (parent ){
Subclass. Prototype = parent. Prototype;
Klass. Prototype = new subclass;
// Add a subclass for the parent class to maintain the subclass set of the parent class
Parent. subclasses. Push (Klass );
}
// Add a method to the new class
For (VAR I = 0; I <properties. length; I ++)
Klass. addmethods (properties [I]);
// If no initialization method is specified, an empty method is assigned to the initialization method by default.
If (! Klass. Prototype. initialize)
Klass. Prototype. initialize = prototype. emptyfunction;
/*
* Modify the constructor of the new class so that the constructor points to itself. Here, I will make a special remark (if the following line is commented out ):
* Var person = Class. Create ();
* Var p1 = new person ();
* Alert (p1.constructor = person) // true
* Var man = Class. Create (person)
* Var M1 = new man ();
* Alert (m1.constrcutor = man) // false
* Alert (m1.constrcutor = person) // true
* Alert (m1.construcctor = p1.constrcutor) // true
*
* Do you see the problem? The man constructor actually points to the person constructor.
* The root cause of the problem is Klass. Prototype = new subclass;
* I will not explain the specific reasons. For more information, see JavaScript language essence and programming practices 155 ~ Page 1
*/
Klass. Prototype. constructor = Klass;
Return Klass;
}
// Add the method used to create a class to the new class, or add a class-level method after the class is created.
Function addmethods (source ){
// Obtain the parent class of the new class
VaR ancestor = This. superclass & this. superclass. Prototype;
VaR properties = object. Keys (source );
// it seems that the following judgment is always true. I don't know why, but tell me what I know?
If (! Object. Keys ({tostring: true}). Length) {
// If the tostring and valueof methods are rewritten for the new class, add it
If (source. tostring! = Object. Prototype. tostring)
properties. Push ("tostring");
If (source. valueof! = Object. Prototype. valueof)
properties. Push ("valueof");
}
// traverse all methods in the new class declaration
for (VAR I = 0, length = properties. length; I // Property indicates the function name and value indicates the function body.
var property = properties [I], value = source [property];
// determines whether the method needs to call a method of the same name as the parent class.
If (ancestor & object. isfunction (value) &
value. argumentnames (). first () = "$ super") {
VaR method = value;
// This is important!
// Replace the $ super parameter so that this parameter points to the method with the same name as the parent class
// The function's wrap method is applied here, for more information about the wrap method, see [Prototype Learning -- function object]
// method is a newly defined method, so its first parameter is $ super, then, from '=' '. 'returns the Same Name method of the parent class
// finally, the wrap method is called to replace the $ super parameter with the same name method of the parent class. In this way, when the subclass calls $ super, the method with the same name of the parent class will be called
// The structure is very good! It is worth thinking about
value = (function (m) {
return function () {return ancestor [M]. apply (this, arguments) ;};
}( property ). wrap (method);
// Point the valueof and tostring of the new value (that is, the modified subclass method) to the same name method of the atomic class.
// Here is the legacy problem after the wrap method is called.
Value. valueof = method. valueof. BIND (method );
Value. tostring = method. tostring. BIND (method );
}
// Add the method to the new class
This. Prototype [property] = value;
}
Return this;
}
// Return the callable method of class
Return {
Create: create,
Methods :{
Addmethods: addmethods
}
};
})();
This class provides two methods: Create and addmethods. The above source code comments have clearly been described. Here are some examples to illustrate the usage:Copy codeThe Code is as follows: // declare the person class and define the initialization method.
VaR person = Class. Create ({
Initialize: function (name ){
This. Name = Name;
},
Say: function (Message ){
Return this. Name + ':' + message;
}
});
// When subclassing, specify the class you want to inherit from
VaR pirate = Class. Create (person ,{
// Redefine the Speak Method
// Pay attention to the $ super usage here. Take a closer look at the explanations in the source code.
Say: function ($ super, message ){
Return $ super (Message) + ', yarr! ';
}
});
VaR John = new pirate ('long john ');
John. Say ('ahoy mate ');
//-> "Long John: Ahoy Matey, yarr! "Copy codeThe Code is as follows: var John = new pirate ('long john ');
John. Sleep ();
//-> Error: sleep is not a method
// Every person shocould be able to sleep, not just pirates!
// Here is the addmethods usage, which can be expanded at the class level
Person. addmethods ({
Sleep: function (){
Return this. Say ('zzz ');
}
});
John. Sleep ();Copy codeThe Code is as follows: // the usage of the superclass and subclasses attributes
Person. superclass
//-> Null
Person. subclasses. Length
//-> 1
Person. subclasses. First () = pirate
//-> True
Pirate. superclass = person
//-> True
Three examples several cover the class method, for detailed examples see: http://prototypejs.org/learn/class-inheritance