Inheritance implementation in 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. Both the inheritance and the inherited sides are "classes". The Code is as follows: first define a parent class (or superclass): 1 function Person (name) {2 this. name = name; 3} 4 5 Person. prototype. getName = function () {6 return this. name; 7}; the property of the parent class person is defined in the constructor, which ensures that the name property inherited from it does not share this property with it, but belongs to the subclass 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 as F, so that its prototype is the prototype of the parent class, in addition, let the prototype of the subclass point to an instance of Class F, thus achieving an inherited parent class At the same time, because the prototype of the subclass has been modified, the constructor attribute of the modified prototype points to the subclass so that it has the constructor and attaches a superClass attribute to the subclass, the Child class can call the parent class through this attribute to establish the relationship between the Child class and the parent class. Define a subclass Author to inherit the parent class Person, as shown below: 1 function Author (name, books) {2 Author. superClass. constructor. call (this, name); 3 this. book = books; 4} 5 extend (Author, Person); 6 Author. prototype. getBooks = function () {7 return this. book; 8} 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, let the subclass Author also have (inherit) the attributes of the parent class, And the subclass also has its own attribute book, so the parameter books is assigned to the attribute book in the constructor to achieve the purpose of construction. 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: The original type inheritance first defines a parent class. Here, it does not deliberately imitate the use of constructor for definition, but directly defines an object using the object literal volume, this object is the parent class 1 var Person = {2 name: 'default name', 3 getName: function () {4 return this. name; 5} 6 7}; like the first method, this object has an attribute name and a method getName. then define a clone method to inherit the parent class from the subclass, as shown in the following code: 1 function clone (obj) {2 function F () {} 3 F. prototype = obj; 4 return new F (); 5} the 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: 1 var Author = clone (Person); 2 Author. book = ['javascript ']; 3 Author. showBook = function () {4 return this. book; 5} defines a subclass here. The clone function inherits the parent class Person and extends 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 it is different, 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 mode, we provide a method of adding a metadata class: First, we 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 expansion, so that the added class has some methods and attributes of the class. If multiple Metadata classes are defined, when added to a class at the same time, this class indirectly implements "Multi-inheritance". Based on this idea, the implementation is as follows: Metadata class definition: 1 var Mixin = function (){}; 2 Mixin. prototype = {3 serialize: function () {4 var output = []; 5 for (key in this) {6 output. push (key + ":" + this [key]); 7} 8 return output. join (','); 9} 10} the metadata class has a serialize method used to traverse itself, output its own attributes and attribute values, and take them as strings Returns, 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: 1 function augment (receivingClass, givingClass) {2 if (arguments [2]) {3 for (var I = 2, len = arguments. length; I <len; I ++) {4 receivingClass. prototype [arguments [I] = givingClass. prototype [arguments [I]; 5} 6} 7 else 8 {9 for (methodName in givingClass. prototype) {10 if (! ReceivingClass. prototype [methodName]) {11 receivingClass. prototype [methodName] = givingClass. prototype [methodName]; 12} 13} 14 15} 16} The method defaults to two parameters. The first parameter is the class to be extended, the second parameter is a metadata class (used to expand the classes of other classes). Other parameters can also be added. If there are more than two parameters, the following parameters are both method or attribute names, indicates that the extended class only inherits the specified attributes or methods of the Child class. Otherwise, all attributes and methods of the Child class are inherited by default. In this function, the first if branch is used to inherit the specified attributes and methods. else branch inherits 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 multi-inheritance 1 augment (Author, Mixin); 2 var author = new Author ('js', ['javascript design patters']); 3 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.