Javascript Object-Oriented Programming (II): constructor inherited by Ruan Yifeng, the first part of the series, mainly introduces how to & quot; encapsulate & quot; data and methods, and how to generate instances from prototype objects. Today, we will introduce the five methods of inheritance between objects. For example, there is a... SyntaxHighlig
Javascript Object-Oriented Programming (II): inheritance of Constructor
Author: Ruan Yifeng
The first part of this series describes how to "encapsulate" data and methods, and how to generate instances from prototype objects.
Today, we will introduce five methods of "inheritance" between objects.
For example, there is an "animal" object constructor.
Function Animal (){
This. species = "animal ";
}
There is also a constructor for the "cat" object.
Function Cat (name, color ){
This. name = name;
This. color = color;
}
How can we inherit "Animals" from "Cats?
I. constructor binding
The first method is also the simplest method. Use the call or apply method to bind the constructor of the parent object to the sub-object, that is, add a row to the sub-object constructor:
Function Cat (name, color ){
Animal. apply (this, arguments );
This. name = name;
This. color = color;
}
Var cat1 = new Cat ("Da Mao", "yellow ");
Alert (cat1.species); // animal
Ii. prototype mode
The second method is more common. The prototype attribute is used.
If the prototype object of "cat" points to an Animal instance, then all "cat" instances can inherit Animal.
Cat. prototype = new Animal ();
Cat. prototype. constructor = Cat;
Var cat1 = new Cat ("Da Mao", "yellow ");
Alert (cat1.species); // animal
In the first line of the code, we direct the prototype object of Cat to an Animal instance.
Cat. prototype = new Animal ();
It is equivalent to deleting the original value of the prototype object and then assigning a new value. But what does the second line mean?
Cat. prototype. constructor = Cat;
Originally, any prototype object has a constructor attribute pointing to its constructor. If there is no "Cat. prototype = new Animal ();" line, Cat. prototype. constructor points to Cat. After adding this line, Cat. prototype. constructor points to Animal.
Alert (Cat. prototype. constructor = Animal); // true
More importantly, each instance also has a constructor attribute. By default, the constructor attribute of the prototype object is called.
Alert (cat1.constructor = Cat. prototype. constructor); // true
Therefore, after running "Cat. prototype = new Animal ();", cat1.constructor also points to Animal!
Alert (cat1.constructor = Animal); // true
This obviously leads to the disorder of the inheritance chain (cat1 is generated by the constructor of the Cat. prototype object). Therefore, we must manually correct the constructor value of the Cat. prototype object to Cat. This is what the second line means.
This is a very important point. It is essential to comply with programming. This is observed in the following sections, that is, if the prototype object is replaced,
O. prototype = {};
Then, the next step is to add the constructor attribute to the new prototype object and direct the attribute back to the original constructor.
O. prototype. constructor = o;
Iii. Directly inherit prototype
The third method is to improve the second method. Because Animal objects can directly write unchanged attributes to Animal. prototype. Therefore, we can also let Cat () skip Animal () and inherit Animal. prototype directly.
Now, we will first rewrite the Animal object:
Function Animal (){}
Animal. prototype. species = "Animal ";
Next, point the prototype object of Cat to the prototype object of Animal to complete inheritance.
Cat. prototype = Animal. prototype;
Cat. prototype. constructor = Cat;
Var cat1 = new Cat ("Da Mao", "yellow ");
Alert (cat1.species); // animal
Compared with the previous method, this method is more efficient (you do not need to execute or create an Animal instance) and saves memory. The disadvantage is that Cat. prototype and Animal. prototype point to the same object. Any modifications to Cat. prototype will be reflected in Animal. prototype.
Therefore, the above Code is actually problematic. See the second line.
Cat. prototype. constructor = Cat;
In fact, the constructor attribute of the Animal. prototype object is also removed!
Alert (Animal. prototype. constructor); // Cat
4. Use empty objects as intermediary
Because "directly inheriting prototype" has the preceding disadvantages, there is a fourth method that uses an empty object as an intermediary.
Var F = function (){};
F. prototype = Animal. prototype;
Cat. prototype = new F ();
Cat. prototype. constructor = Cat;
F is a null object, so it hardly occupies memory. In this case, modifying the prototype object of Cat will not affect the prototype object of Animal.
Alert (Animal. prototype. constructor); // Animal
We encapsulate the above method into a function for ease of use.
Function extend (Child, Parent ){
Var F = function (){};
F. prototype = Parent. prototype;
Child. prototype = new F ();
Child. prototype. constructor = Child;
Child. uber = Parent. prototype;
}
The method is as follows:
Extend (Cat, Animal );
Var cat1 = new Cat ("Da Mao", "yellow ");
Alert (cat1.species); // animal
This extend function is how the YUI library implements inheritance.
In addition, one note is that the last row of the function body
Child. uber = Parent. prototype;
This parameter sets an uber attribute for the sub-object. This attribute directly points to the prototype attribute of the parent object. (Uber is a German word, meaning "up" and "up ".) This is equivalent to opening a channel on the sub-object. You can directly call the method of the parent object. This line is put here only to realize the completeness of inheritance, which is purely standby.
V. Copy inheritance
The above uses prototype objects to implement inheritance. We can also use the "copy" method to implement inheritance. Simply put, if we copy all the attributes and methods of the parent object into the sub-object, can we still implement inheritance? In this way, we have the fifth method.
First, put all the unchanged attributes of Animal on its prototype object.
Function Animal (){}
Animal. prototype. species = "Animal ";
Then, write a function to copy the attributes.
Function extend2 (Child, Parent ){
Var p = Parent. prototype;
Var c = Child. prototype;
For (var I in p ){
C [I] = p [I];
}
C. uber = p;
}
This function is used to copy the attributes of the prototype object of the parent object to the prototype object of the Child object.
Write as follows:
Extend2 (Cat, Animal );
Var cat1 = new Cat ("Da Mao", "yellow ");
Alert (cat1.species); // animal