Whenever we talk about JS inheritance, the first reaction in your head is to prototype the prototype mechanism to achieve it. But have you used other methods to implement inheritance, or do you understand the pros and cons of other implementations and various inheritance implementations?
OK, let's take a look at some of the more common inheritance implementations.
1, prototype way
var baseclass = function ()
{this
. Name = "3ZFP";
this. Age = M ;
this. ToString = function () {return this . Name + ' " + this. age;
}
}
var Derived = function ()
{this
. Address = "Shenzhen";
}
Derived.prototype = new baseclass ();
var instance = new Derived ();
Instance. ToString ();
The easiest way to do this is to simply make the prototype of a class OK for an inherited instance, and then use the BaseClass method directly.
What does the prototype attribute mean? Prototype is a prototype, and each object (defined by function) has a default stereotype property, which is an object type. And the default property is used to implement the chain upward climb. This means that if an object's properties do not exist, that object's properties will be looked up by the object corresponding to the prototype property. If the prototype can't find it. JS will automatically find the corresponding object of the prototype prototype property to find, so that through the prototype has been climbed up the index until the property found or prototype finally empty ("undefined");
For example, the instance in the previous example. ToString () method. JS will first find in the instance instance whether there is a ToString () method, because there is no, so look for the Derived.prototype property, and prototype is an instance of Newclass, the instance has the ToString () method, The call succeeds and the instance Name property is also assigned to find the prototype to implement.
Note that each object is prototype by default to an object, but the object is not equal to object; Look at the following code:
var foo = function () {};
var result =
The result of this code value is false;
Here are a few points to note:
typeof (Object.prototype) = = "Object";
typeof (Object.prototype.prototype) = = "undefined";
var obj = new Object ();
typeof (Obj.prototype) = = "undefined";
var obj = {};
typeof (Obj.prototype) = = "undefined";
2, apply the way
var baseclass = function ()
{this
. Name = "3ZFP";
this. Age = M ;
this. ToString = function () {return this . Name + ' " + this. age;
}
}
var Derived = function ()
{
baseclass.apply (this, new Array ());
this. Address = "Shenzhen";
}
var instance = new Derived ();
Instance. ToString ();
In this way, what we need to understand most is the role of the Apply function.
The method is generally interpreted as replacing the B method with A method. The first parameter is the object itself of the B method, the second argument is an array, and the value in the array is the list of arguments that need to be passed to the A method, and Null is not valid if the argument is null, that is, if there is no parameter passing, the new array () is passed.
The General Way is:
In this case, however, the Apply method performs a two-step operation.
The first one is to instantiate the BaseClass with the array array as the initialization parameter.
Second : Copy all properties of the newly generated instance object (Name,age, ToString method) to the instance instance object. This enables inheritance.
var foo = function ()
{this
. Fooa = function () {this
. foob.apply (This, new< C11/>array ("sorry"));
}
this. Foob = function (str)
{
alert (str);
}
}
New foo (). Fooa ();
3, Call+prototype Way
var baseclass = function (name,age)
{this
. Name = name;
this. Age = Age ;
this. ToString = function () {return this . Name + ' " + this. age;
}
}
var Derived = function ()
{
Baseclass.call (this, "3ZFP");
this. Address = "Shenzhen";
}
Derived.prototype = new baseclass ();
var instance = new Derived ();
Instance. ToString ();
In fact, the call function and the Apply method has a very similar role, are using a method to replace the B method, but the parameter transmission is not the same, the call method's first parameter is the B method of the object itself, and the parameter column and the array object packaging, direct transmission can be.
Why the function is similar, call Way's realization mechanism but wants one more derived.prototype = new BaseClass (); Statement. That's because the call method only implements the substitution of the method and does not copy the object attribute.
The call method actually does the following several things:
Cases:
var foo = function ()
{this
. Fooa = function () {this
. Foob.call (This, "sorry " );
}
this. Foob = function (str)
{
alert (str);
}
}
New foo (). Fooa ();
Then This.fooB.call (this, "sorry") performs the following actions: 1 this. temp = this. Foob;
2
3. Temp ("sorry");
4
5 Delete (this. temp);
6
In fact, the inheritance of the Google Map API is to use this approach. You can download the reference reference (maps.google.com).
4, Prototype.js in the implementation of the way
Object.extend = function (destination, source) {for (property in source) {
Destination[property] = source[property];
}
return destination;
}
var baseclass = function (name,age) {this
. Name = name;
this. Age = Age ;
this. ToString = function () {return this . Name + ' " + this. age;
}
}
var Derived = function ()
{
Baseclass.call (this, "foo");
this. Address = "singapore";
this. ToString = function () {
var string = Derived.prototype.ToString.call (this);
Return string + ' "+ this . Address;
Object.extend (Derived.prototype, New BaseClass ());
var instance = new Derived ();
This way, in fact, is an explicit use of the principle of apply to achieve inheritance. First var temp = new BaseClass (), and then the property traversal of temp is copied into Derived.prototype. For (the property in source) represents all the properties that traverse an object. However, private properties cannot be traversed. Cases:
var foo = function ()
2
3 {
4
5 var innerstring = "";
6
7 this . Name = "3ZFP";
8
9 this . Age = M ;
A function innertostring () { return innerstring; var f = new foo (); var eles = "";
For
(property in f) eles = " " + property;
document.write (eles);
The output is "name age" without "innerstring" and "innertostring ()"; The specific principle, which can be explained later (including private variables, private functions, variable accessibility of private functions, etc.). The above summarizes the implementation of various ways of inheritance. But each method has its advantages and disadvantages.
The first way, how to achieve the following requirements, need to show "3zfp__100";
var baseclass = function (name,age)
2
3 {
4
5 this . Name = name;
6
7 this . Age = Age ;
8
9 This . ToString = function () {
a . Name + " " + this. Age;
The var Derived = function (name,age)
This . Address = "Shenzhen";
Derived.prototype = new baseclass ();
MB var instance = new Derived ("3ZFP");
document.write (instance. ToString ());
31
We can find by running that the output is actually "undefined__undefined". This means that the name and age are not assigned values.
Oh,my god! Despair The second and third methods can be implemented, as follows:
var baseclass = function (name,age) 2 3 {4 5 this. Name = name;
6 7 this. Age = age; 8 9 this.
ToString = function () {A. Name + "" + this. age; The var Derived = function (name,age) is baseclass.apply (thi.)
S, New Array (Name,age));
this. Address = "Shenzhen";
MB var instance = new Derived ("3ZFP", 100); document.write (instance.
ToString ()); ______________________________________________-------------------------------------------------------- -------------var baseclass = function (name,age) {40-name = NAME = 41
this. Age = age; This is the only.
ToString = function () {A. Name + "" + this. age; Derived var = function (Name,age) 52 53 {54
Baseclass.call (this, name,age);
this. Address = "Shenzhen";
Derived.prototype = new BaseClass ();
The var instance = new Derived ("3ZFP", 100); document.write (instance).
ToString ()); 68 69 70
But the application method also has shortcomings, why. In JS, we have a very important operator that is "instanceof", which is used to compare whether a pair of pairs is of a certain type. For inheritance, we should be in addition to the derived type, but also the BaseClass type. The Apply method returns a value of False ((instance instanceof BaseClass) = = false). This problem can also occur because Prototype.js uses a similar method of apply.
Ah, the ultimate method is Call+prototype way, or Google Bull X. You can try it correctly ((instance instanceof baseclass) = = True).
Finally, it is multiple inheritance, because JS prototype can only correspond to one object, so can not achieve a real sense of multiple inheritance. A JS library simulates multiple inheritance, but the library also overrides the Instanceof method, using _instanceof and _subclassof functions to simulate judgments. The library's name is Modello.js, interested in the search can be downloaded.