Three methods of inheritance and examples in JavaScript, and three methods of javascript
Although javascript is an object-oriented language, Its Inheritance Mechanism was designed from the very beginning. It is different from other traditional object-oriented languages and is a prototype-based Inheritance Mechanism, however, under this mechanism, inheritance still has some different implementation methods.
Method 1: class inheritance
The so-called class inheritance refers to the inheritance method that imitates the traditional object-oriented language. The inherited and inherited sides are both "classes". The Code is as follows:
First define a parent class (or superclass ):
function Person(name){ this.name=name; } Person.prototype.getName=function(){ return this.name; };
The attributes of the parent class person are defined in the constructor, which ensures that the name attribute of the Child class that inherits it does not share this attribute with it, but belongs to the Child class separately, the getName method is mounted to the prototype to allow multiple instances that inherit its subclass to share this method body, which saves memory (for multiple instances, every time a New instance comes out, the getName method of these instances references the same memory space, rather than independent space ).
Define an inheritance method extend as follows:
function extend(subClass,superClass){ var F=function(){}; F.prototype=superClass.prototype; subClass.prototype=new F(); subClass.prototype.constructor=subClass; subClass.superClass=superClass.prototype; if(superClass.prototype.constructor==Object.prototype.constructor){ superClass.prototype.constructor=superClass; } }
In this method, first create a new class F, let its prototype be the prototype of the parent class, and let the prototype of the subclass point to an instance of the Class F, in this way, a parent class can be inherited. At the same time, because the prototype of the subclass is modified, the constructor attribute of the modified prototype points to the subclass so that it has a constructor, at the same time, a superClass attribute is attached to the subclass. The subclass can call the parent class through this attribute to establish the relationship between the subclass and the parent class.
Define a subclass Author to inherit the parent class Person, as follows:
function Author(name,books){ Author.superClass.constructor.call(this,name); this.book=books; } extend(Author,Person); Author.prototype.getBooks=function(){ return this.book; }
Here, the constructor of the parent class is called through its superClass attribute in the constructor of the subclass. At the same time, the call method is used to convert this point called by this method so that the subclass Author can also have (inherit) the attributes of the parent class, and the Child class has its own attribute book. Therefore, the parameter books is assigned to the attribute book in the constructor to achieve the goal of constructing. The extend function is used to inherit the attributes and methods of the parent class Person prototype (in fact, only the methods are inherited, because we just mounted the methods to the prototype, properties are defined in the constructor ). At the same time, Author has its own method getBooks, Which is mounted to the corresponding prototype to further expand itself on the basis of inheritance.
This Inheritance Method is obviously similar to the traditional object-oriented language class inheritance. The advantage is that it is easy to understand for programmers who are used to the traditional object-oriented concepts. The disadvantage is that the process is cumbersome, memory consumption is slightly higher, because the subclass also has its own constructor and prototype, and the attributes of the subclass and the parent class are completely isolated, even if the two are the same value, however, the same memory segment cannot be shared.
Method 2: original type inheritance
First, define a parent class, which is defined by the constructor rather than the object literal. The object is the parent class.
var Person={ name:'default name', getName:function(){ return this.name; } } ;
Like the first method, the object has an attribute name and a method getName.
Then, define a clone method to inherit the parent class from the subclass, as shown below:
function clone(obj){ function F(){} F.prototype=obj; return new F(); }
This clone method creates an object, points the prototype of the object to the parent class, that is, the parameter obj, and returns the object.
The Child class inherits the parent class through the clone function, as shown below:
var Author=clone(Person); Author.book=['javascript']; Author.showBook=function(){ return this.book; }
Here, we define a subclass, inherit the parent class Person through the clone function, and expand an attribute book and a method showBook. This subclass also has the attribute name, but it is the same as the name value of the parent class, so it is not overwritten. If not, you can use
Author. name = 'new name'; overwrites this attribute to obtain a new name attribute value of the subclass.
Compared with class inheritance, the original type inheritance is simpler and more natural. If the attributes of the subclass are the same as those of the parent class, the two actually share the same memory space. The disadvantage of the above name attribute is that it is hard for traditional object-oriented programmers to understand. If the two are to be selected, undoubtedly, this method is better.
Since javascript uses prototype-based inheritance, and each object prototype can only point to an instance of a specific class (not to multiple instances ), so how to implement multi-inheritance (that is, to make a class have multiple classes of methods and attributes at the same time, and itself does not define these methods and attributes )?
In the javascript design pattern, we provide a method of adding a metadata class:
First, define a metadata class to save some common methods and attributes. These methods and attributes can be added to any other class by means of extension, therefore, the added class has some methods and attributes of the class. If multiple Metadata classes are defined and added to a class, the class indirectly implements "Multi-inheritance ", based on this idea, the implementation is as follows:
Definition of metaclasses:
var Mixin=function(){}; Mixin.prototype={ serialize:function(){ var output=[]; for(key in this){ output.push(key+":"+this[key]); } return output.join(','); } }
The metadata class has a serialize method that is used to traverse itself, output its own attributes and attribute values, and return them as strings, separated by commas.
Define an extension method to enable a class to have the attributes or methods of the meta-classes after expansion, as follows:
function augment(receivingClass,givingClass){ if(arguments[2]){ for(var i= 2,len=arguments.length;i<len;i++){ receivingClass.prototype[arguments[i]]=givingClass.prototype[arguments[i]]; } } else { for(methodName in givingClass.prototype){ if(!receivingClass.prototype[methodName]){ receivingClass.prototype[methodName]=givingClass.prototype[methodName]; } } } }
By default, this method has two parameters. The first parameter is the class to be extended, the second parameter is the metadata class (used to expand the classes of other classes), and other parameters can be added, if there are more than two parameters, the following parameters are both method or attribute names, which indicate that the extended class only wants to inherit the specified attribute or method of the metadata class, otherwise, all attributes and methods of the metadata class are inherited by default. In this function, the first if branch is used to inherit the specified attributes and methods, else branches inherit all attributes and methods by default. The essence of this method is to expand (ADD) the attributes and methods on the prototype of the metadata class to the prototype of the extended class, so that it has the attributes and methods of the metadata class.
Finally, use the extension method to implement multiple inheritance
augment(Author,Mixin); var author= new Author('js',['javascript design patterns']); alert(author.serialize());
An author class is defined here, which inherits from the Person parent class and has the methods and attributes of the meta-class Mixin. If you want, you can define N meta-classes to expand the class. It can also inherit the attributes and methods of other meta-classes you define, so that multiple inheritance is realized. Finally, the running result of the serialize method of author is as follows:
You will find that this class has the attributes and methods of the person, Author, and Mixin classes. The attributes and methods of the Person and Mixin classes are inherited. In fact, it implements multiple inheritance.