Home >Web Front-end >JS Tutorial >Prototype Class object learning_prototype

Prototype Class object learning_prototype

WBOY
WBOYOriginal
2016-05-16 18:49:57902browse
Copy code The code is as follows:

/* Based on Alex Arnell's inheritance implementation. */

var Class = (function() {
//Temporarily store the parent's prototype
function subclass() {} ;

//Method to create a class
function create() {
var parent = null, properties = $A(arguments);
//Check whether to specify when creating a new class A parent object
//If a parent class is specified, assign the value to parent
if (Object.isFunction(properties[0]))
parent = properties.shift();

//The class actually used to return, 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 for class-level method expansion
Object.extend(klass, Class.Methods);
// Add two attributes to the returned class, superclass: parent class, subclasses: collection of subclasses
klass.superclass = parent;
klass.subclasses = [];

//If you create a class When the parent object is specified, point the prototype of klass to the instance of the parent object to implement prototype chain inheritance
if (parent) {
subclass.prototype = parent.prototype;
klass.prototype = new subclass;
//Add subclasses to the parent class and maintain the subclass collection of the parent class
parent.subclasses.push(klass);
}

//Add methods 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 will be used by default Assign to the initialization method
if (!klass.prototype.initialize)
klass.prototype.initialize = Prototype.emptyFunction;

/*
* Correct the constructor of the new class so that the constructor The function points to itself, here is a special mention (if you comment out the following line):
* 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? Man's constructor actually points to Person's constructor
* The root of the problem lies in the sentence klass.prototype = new subclass;
* I will not explain the specific reason. For a detailed understanding, please see "JavaScript Language" Essence and Programming Practice" pages 155~160
*/
klass.prototype.constructor = klass;
return klass;
}

//Add the method when creating the class to a new class, or add a class-level method after creating the class
function addMethods(source) {
//Get 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 it is written like this. If you know, tell me?
if (!Object .keys({ toString: true }).length) {
//If the new class overrides the toString and valueOf methods, add them
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 < length; i ) {
//property is the function name, value is the function body
var property = properties[i], value = source[property];
//Determine whether this method needs to call the method of the same name of the parent class
if (ancestor && Object.isFunction(value) &&
value.argumentNames ().first() == "$super") {
var method = value;
   //This is very important!
//Replace the $super parameter so that this parameter points to the method of the same name of the parent class
//The wrap method of Function is used here. For the explanation of the wrap method, please refer to [Prototype Learning - Function Object]
/ /Method is a new definition method, so his first parameter is $ super, and then returns from '=' to '.' to return the method of the same name
// Replace the parameters with the method of the same name of the parent class, so that when the subclass calls $super(), the method of the same name of the parent class will be called
//The construction here is great!Worth thinking about
value = (function(m) {
return function() { return ancestor[m].apply(this, arguments); };
})(property).wrap(method);

//Point the valueOf and toString of the newly generated value (i.e. the modified subclass method) to the method of the same name of the atomic class
🎜>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 2 methods: create and addMethods, which are clearly explained in the source code comments above. Let’s look at some examples to explain the usage in detail:

Copy code The 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
//Note the usage of $super here, check the explanation in the source code Take a closer look
say: function($super, message) {
return $super(message) ', yarr!';
}
});

var john = new Pirate('Long John');
john.say('ahoy matey');
// -> "Long John: ahoy matey, yarr!"



Copy code The code is as follows:
var john = new Pirate('Long John');
john.sleep();
// -> ERROR: sleep is not a method
// every person should be able to sleep, not just pirates!

//This is The usage of addMethods can be extended at the class level.
Person.addMethods({
sleep: function() {
return this.say('ZzZ');
}
});
john.sleep();



Copy code The code is as follows:
//Here are the usage of the two attributes superclass and subclasses

Person.superclass
// -> null
Person.subclasses.length
// - > 1
Person.subclasses.first() == Pirate
// -> true
Pirate.superclass == Person
// -> true


The three examples cover the methods of the Class class. For detailed examples, please refer to: http://prototypejs.org/learn/class-inheritance

Statement:
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn