The inheritance mechanism javascript

Inheritance mechanism

Use ECMAScript implementation inheritance, you can start from a base class to inherit. All developer-defined classes can be used as a base class. For security reasons, the local host classes and classes can not be used as a base class, so public access to compiled browser-level code to prevent, because the code can be used for malicious attacks.

After selecting a base class, you can create a subclass of it. Whether to use a base class entirely up to you. Sometimes, you may want to create a base class can not be directly used, it is only used to provide a common sub-type of function. In this case, as an abstract class is a base class.

Although ECMAScript not as strictly defined abstract class like any other language, but sometimes it does create some kind allowed. Usually, we call this class is an abstract class.

Create a subclass will inherit all the properties and methods of the superclass, including the realization of constructors and methods. Remember, all properties and methods are public, so subclasses can directly access these methods. Subclasses may not add new attributes and methods of the superclass, properties and methods of superclasses may be covered.

Inheritance way

And other functions, like, ECMAScript implementation inheritance more than one way. This is because the inheritance mechanism of JavaScript is not clearly defined, but by imitating achieved. This means that all the details are not fully processed inherited by an interpreter. As a developer, you have the right to decide the most appropriate way of inheritance.

Here to introduce you several specific inheritance.

Object masquerading

When the original idea of ​​ECMAScript, did not intend to design objects posing (object masquerading). It is in developers beginning to understand the function works, especially how to use this keyword in the function developed after the environment.

The principle is as follows: constructor this keyword assigned to all the properties and methods (i.e., using a constructor argument class declaration). Because the constructor is just a function, it can become a constructor method ClassA ClassB, and then call it. You will receive ClassB constructor properties and methods defined in ClassA. For example, ClassA and ClassB defined in the following manner:

function ClassA(sColor) {
    this.color = sColor;
    this.sayColor = function () {
        alert(this.color);
    };
}

function ClassB(sColor) {
}

do you remember? The keyword this refers to the current constructor to create built objects. However, in this method, this points to an object belongs. This principle is ClassA as a regular function to establish the inheritance mechanism, rather than as a constructor. Use the following ClassB constructor inheritance mechanism can be achieved:

function ClassB(sColor) {
    this.newMethod = ClassA;
    this.newMethod(sColor);
    delete this.newMethod;
}

In this code, a method for the ClassA given newMethod (Remember, the function name just a pointer to it). The method is then invoked, it is passed to the constructor parameter sColor ClassB. The last line of code to delete the reference to ClassA, so that later you can not call it.

All the new properties and methods must be defined after deleting the lines of the new method. Otherwise, it may cover the properties and methods of the superclass:

function ClassB(sColor, sName) {
    this.newMethod = ClassA;
    this.newMethod(sColor);
    delete this.newMethod;

    this.name = sName;
    this.sayName = function () {
        alert(this.name);
    };
}

To prove the preceding code is valid, the following examples can be run:

var objA = new ClassA("blue");
var objB = new ClassB("red", "John");
objA.sayColor();	//输出 "blue"
objB.sayColor();	//输出 "red"
objB.sayName();		//输出 "John"

Posing as real objects can now multiple inheritance

Interestingly, posing as an object can support multiple inheritance. In other words, a class can inherit more than one superclass. Multiple inheritance mechanism in UML as shown below:

For example, if there are two classes ClassX and ClassY, ClassZ want to inherit two classes, you can use the following code:

function ClassZ() {
    this.newMethod = ClassX;
    this.newMethod();
    delete this.newMethod;

    this.newMethod = ClassY;
    this.newMethod();
    delete this.newMethod;
}

TIY

This was a drawback exists, if two or class attributes and methods ClassX CLASSY having the same name exists, CLASSY has a high priority. Because it inherits from the back of the class. In addition to this little problem with object masquerading easy to achieve multiple inheritance.

As the popularity of this method of inheritance, EC MAScript the third edition of the Function object added two methods, namely call () and apply ().

call () method

call () method is the method most classical objects posing a similar way. Its first object is used as a parameter of this. Other parameters are directly passed to the function itself. E.g:

function sayColor(sPrefix,sSuffix) {
    alert(sPrefix + this.color + sSuffix);
};

var obj = new Object();
obj.color = "blue";

sayColor.call(obj, "The color is ", "a very nice color indeed.");

In this example, the function sayColor () is defined outside the object, even if it does not belong to any object, may be cited keyword this. Color property of object obj is equal to blue. When you call call () method, the first argument is obj, instructions should be given sayColor () this function key values ​​are obj. The second and the third argument is a string. They () parameters and sSuffix sPrefix sayColor match function, and finally generated message "The color is blue, a very nice color indeed." Will be displayed.

To the inheritance mechanism used with the method object masquerading method, simply assign the first three rows, delete and replace the code to call:

function ClassB(sColor, sName) {
    //this.newMethod = ClassA;
    //this.newMethod(color);
    //delete this.newMethod;
    ClassA.call(this, sColor);

    this.name = sName;
    this.sayName = function () {
        alert(this.name);
    };
}

TIY

Here, we need to make the keywords in this ClassA ClassB equal to the newly created object, so this is the first parameter. The second argument sColor for two classes are unique parameters.

apply () method

apply () method has two parameters, and this object is used to pass arguments to a function of the array. E.g:

function sayColor(sPrefix,sSuffix) {
    alert(sPrefix + this.color + sSuffix);
};

var obj = new Object();
obj.color = "blue";

sayColor.call(obj, new Array("The color is ", "a very nice color indeed."));

This example is the same as the previous example, but now is called apply () method. When calling apply () method, the first parameter is still obj, instructions should be given sayColor () this function key values ​​are obj. The second parameter is an array of two character strings, and with sayColor sPrefix sSuffix matching function parameters in (), and finally still generated message "The color is blue, a very nice color indeed.", Will be displayed come out.

This method is also used to replace the first three rows of the assignment, and remove the code calls the new method:

function ClassB(sColor, sName) {
    //this.newMethod = ClassA;
    //this.newMethod(color);
    //delete this.newMethod;
    ClassA.apply(this, new Array(sColor));

    this.name = sName;
    this.sayName = function () {
        alert(this.name);
    };
}

Similarly, the first argument is still this, the second parameter is an array of only one color value. Arguments can ClassB entire object as the second argument to apply () method:

function ClassB(sColor, sName) {
    //this.newMethod = ClassA;
    //this.newMethod(color);
    //delete this.newMethod;
    ClassA.apply(this, arguments);

    this.name = sName;
    this.sayName = function () {
        alert(this.name);
    };
}

TIY

Of course, the order parameter and the parameter order subclasses of super class only exactly when the same parameter object can be passed. If not, you must create a separate array, placing the parameters in the correct order. Alternatively, use call () method.

Chain prototype (prototype chaining)

This form of inheritance in ECMAScript was originally used for the prototype chain. The previous chapter define the prototype class. Prototype chain extends this way, a fun way to achieve inheritance.

In the last chapter learned, prototype object is a template to instantiate the object to the template-based. In short, any methods and properties of the prototype object are passed to all instances of that class. With this function prototype chain to implement inheritance.

If the prototype embodiment redefine classes in the previous example, they will be changed to the following form:

function ClassA() {
}

ClassA.prototype.color = "blue";
ClassA.prototype.sayColor = function () {
    alert(this.color);
};

function ClassB() {
}

ClassB.prototype = new ClassA();

Prototype approach is that the magic blue lines highlighted. Here, the prototype property ClassB arranged instance of ClassA. This is interesting, because you want all the properties and methods of ClassA, but one by one they do not want ClassB's prototype property. There prototype property better way than giving the example of ClassA do?

Note: ClassA constructor call, do not pass parameters to it. This is standard practice in the prototype chain. To ensure that the constructor has no parameters.

Posing similar object, all the properties and methods of the subclass must occur after the prototype property is assigned, because before it assigned all methods will be deleted. why? Because the prototype property is replaced with new objects, add a new method of original object will be destroyed. Therefore, code is added to the name attribute and sayName ClassB class () method is as follows:

function ClassB() {
}

ClassB.prototype = new ClassA();

ClassB.prototype.name = "";
ClassB.prototype.sayName = function () {
    alert(this.name);
};

This code can be tested by running the following examples:

var objA = new ClassA();
var objB = new ClassB();
objA.color = "blue";
objB.color = "red";
objB.name = "John";
objA.sayColor();
objB.sayColor();
objB.sayName();

TIY

Further, in the prototype chain, instanceof operator operating mode is also unique. All instances of ClassB, instanceof for the ClassA and ClassB return true. E.g:

var objB = new ClassB();
alert(objB instanceof ClassA);	//输出 "true"
alert(objB instanceof ClassB);	//输出 "true"

In ECMAScript weakly typed world, this is an extremely useful tool, but it can not be used when using objects posing.

The drawbacks of the prototype chain does not support multiple inheritance. Remember, the prototype chain class prototype property is rewritten by another type of object.

Mixed mode

This constructor is defined using inheritance class, rather than using any prototype. The main problem is the need to use object masquerading constructor way, this is not the best choice. But if you use the prototype chain, you can not use a constructor with parameters. How developers choose? The simple answer is, both.

In the previous chapter, we have had to explain the best way to create a class constructor is defined using attributes defined by the prototype method. This same applies to the inheritance mechanism, posing the properties inherited by the object constructors, object methods inheritance prototype prototype chain. Examples of using these two methods rewrite the previous code is as follows:

function ClassA(sColor) {
    this.color = sColor;
}

ClassA.prototype.sayColor = function () {
    alert(this.color);
};

function ClassB(sColor, sName) {
    ClassA.call(this, sColor);
    this.name = sName;
}

ClassB.prototype = new ClassA();

ClassB.prototype.sayName = function () {
    alert(this.name);
};

In this example , the inheritance mechanism is implemented by two lines of code blue highlighted. In the first line of code is highlighted, the ClassB constructor posing ClassA class inherits attributes sColor with objects. In the second line of code is highlighted, the method ClassA prototype class inheritance chain. Since such a hybrid approach using prototype chain, so instanceof operator can still operate correctly.

The following examples tested this code:

var objA = new ClassA("blue");
var objB = new ClassB("red", "John");
objA.sayColor();	//输出 "blue"
objB.sayColor();	//输出 "red"
objB.sayName();	//输出 "John"

Guess you like

Origin blog.csdn.net/u012384285/article/details/25899625