First, constructor binding
Let's take a look at the meanings of the following two functions:
functionClassA (scolor) { This. color=Scolor; This. saycolor=function() {alert ( This. color); };} functionClassB (scolor,sname) { This. newmethod=ClassA; This. Newmethod (Scolor); Delete This. Newmethod; This. name=SName; This. sayname=function() {alert ( This. Name); };}
The above code is the inherited function, create a new variable Newmethod, then point the ClassA pointer to the variable, and then call this method in CLASSB. This actually newmethod the scope of the reference, which means that this point is the object ClassB instantiated. Note: The last line removes a reference to ClassA so that it cannot be called later. All new properties and new methods must be defined after the code for the new method is removed, otherwise overriding the related properties and methods of the superclass
To prove the validity of the front, run the following example
var obja=New ClassA ("Red"); var objb=New ClassB ("Blue", "Nicholas"); Obja.saycolor (); Objb.saycolor (); Objb.sayname ();
Because of the popularity of this inheritance method, ECMAScript adds two new methods to the function object, called call () and apply (), so the method above can be overridden with the call or Apply method, binding the parent object's constructor on the child object, That is, add a line to the child object constructor:
function ClassB (scolor,sname) { //This.newmethod=classa; // This.newmethod (scolor); // delete this.newmethod; Classa.call (this, scolor); this. name=sName; this. sayname=function() { alert (this. name);} ;}
As can be seen here, the first three lines of code directly changed to the call method, so for the top example, we change to the following look, we can directly implement the inherited
function Cat (name,color) { animal.apply (this, arguments); this. Name = name; this. color = color;} var New Cat ("Da Mao", "Yellow"// animal
Second, prototype mode
The second method is more common, using the prototype property. If the prototype object of "cat" points to an instance of animal, then all instances of "cat" can inherit animal.
New= Cat; var New Cat ("Da Mao", "Yellow"// animal
The first line of code is that we point the cat's prototype object to an instance of animal.
The second line of code is that any prototype object has a constructor property that points to its constructor. If there is no "Cat.prototype = new Animal ();" In this line, Cat.prototype.constructor is pointing to Cat, and after adding this line, Cat.prototype.constructor points to animal.
//
More importantly, each instance also has a constructor property, which calls the prototype object's constructor property by default.
// true
Therefore, in the run "Cat.prototype = new Animal ();" After this line, Cat1.constructor also points to animal!
// true
This obviously leads to an inheritance chain disorder (CAT1 is obviously generated with the constructor cat), so we have to manually correct the constructor value of the Cat.prototype object to Cat.
Third, direct succession prototype
The third method is the improvement of the second method. Because of the animal object, the invariant property can be written directly to Animal.prototype. So, we can also let cat () skip Animal () and inherit Animal.prototype directly. Now, we'll first rewrite the animal object:
function= "Animal";
The cat's prototype object is then pointed to the animal prototype object, which completes the inheritance.
Cat.prototype == Cat; var New Cat ("Da Mao", "Yellow"// animal
The advantage of doing this compared to the previous method is that it is more efficient (without having to execute and establish an instance of animal) and saves memory. The disadvantage is that Cat.prototype and Animal.prototype now point to the same object, so any changes to the Cat.prototype will be reflected in the Animal.prototype. So, the above piece of code is actually problematic. Take a look at the second line
Cat.prototype.constructor = Cat;
This sentence actually changed the constructor attribute of the Animal.prototype object too!
// Cat
Iv. use of empty objects as intermediaries
Since the "Direct inheritance prototype" has the disadvantages mentioned above, there is a fourth method, using an empty object as the intermediary
var function =new= Cat;
F is an empty object, so it hardly accounts for memory. At this point, modifying the cat's prototype object does not affect the animal prototype object.
// Animal
We encapsulate the above method into a function.
function Extend (Child, Parent) { varfunction() {}; = Parent.prototype; New F (); = Child ; = Parent.prototype;} Extend (cat,animal); var New Cat ("Da Mao", "Yellow"// animal
This extend function, is how Yui Library implements the method of inheriting. In addition, it is stated that
Child.uber = Parent.prototype;
It means setting an Uber property for the sub-object, which points directly to the parent object's prototype property. (Uber is a German word that means "up", "up".) This is equivalent to opening a channel on a child object that can call the parent object's method directly. This line is put here, just to achieve the completeness of inheritance, is purely an alternative nature.
V. Copy inheritance
Above is the use of prototype objects, implementation of inheritance. We can also change a way of thinking, purely using the "copy" method to achieve inheritance. Simply put, if you copy all the properties and methods of the parent object into the child object. So that we have a fifth way of doing it.
First, all the invariant properties of animal are placed on its prototype object.
function= "Animal";
Then, write a function that implements the purpose of the property copy.
function Extend2 (Child, Parent) { var p = parent.prototype; var c = child.prototype; for (var in p) { = p[i]; } = p;}
This function is to copy the attributes from the parent object's prototype object to the prototype object of the child object. One by one When used, write this:
Extend2 (Cat, Animal); var New Cat ("Da Mao", "Yellow"// animal
JavaScript Object-oriented-inheritance