Prototype Class Object Learning

Source: Internet
Author: User

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

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.