A detailed description of the call () method and the Apply () method

Source: Internet
Author: User
Tags define abstract

Implementation of inheritance mechanism by ECMAScript inheritance mechanism

To implement the inheritance mechanism with ECMAScript, you can start with the base class that you want to inherit from. All developer-defined classes are available as base classes. For security reasons, local classes and host classes cannot be used as base classes, which prevents public access to compiled browser-level code because the code can be used for malicious attacks.

Once you have selected a base class, you can create its subclasses. It is up to you to use the base class. Sometimes, you might want to create a base class that you can't use directly, it's just used to provide generic functions to subclasses. In this case, the base class is treated as an abstract class.

Although ECMAScript does not define abstract classes as strictly as in other languages, it does sometimes create classes that are not allowed to be used. In general, we call this class an abstract class.

The subclass you create inherits all the properties and methods of the superclass, including the implementation of constructors and methods. Remember that all properties and methods are common, so subclasses can access these methods directly. Subclasses can also add new properties and methods that are not in the superclass, or override the properties and methods of the superclass.

The way of inheritance

As with other features, ECMAScript implements inheritance in more ways than one. This is because the inheritance mechanism in JavaScript is not explicitly defined, but is implemented by imitation. This means that all inheritance details are not handled entirely by the interpreter. As a developer, you have the right to decide on the most appropriate way to inherit.

Here are some specific ways to inherit.

Object Impersonation

When the original ECMAScript was conceived, there was no intention to design the object to impersonate (object masquerading). It is when developers begin to understand how functions work, especially how to use the This keyword in a function environment to develop.

The principle is as follows: The constructor uses the This keyword to assign values to all properties and methods (that is, the constructor method that takes the class declaration). Because the constructor is just a function, you can make the ClassA constructor a ClassB method and then call it. ClassB will receive the properties and methods defined in the ClassA constructor. For example, define ClassA and ClassB in the following way:

function ClassA (scolor) {    this. color = scolor;       This function () {        alert (this. color);}    ;} function ClassB (scolor) {}

Do you remember? The keyword this refers to the object that the constructor is currently creating. In this method, however, this points to the owning object. This principle is to use ClassA as a regular function to establish the inheritance mechanism, rather than as a constructor function. You can implement the inheritance mechanism using the constructor ClassB as follows:

function ClassA (scolor) {    this. color = scolor;       This function () {        alert (this. color);}    ;} function ClassB (scolor) {}

In this code, ClassA is given the method Newmethod (remember, the function name is just a pointer to it). The method is then called, and passed to it is the parameter scolor of the ClassB constructor. The last line of code removes a reference to ClassA so that it can no longer be called.

All new properties and new methods must be defined after the line of code for the new method has been deleted. Otherwise, the related properties and methods of the superclass may be overwritten:

function ClassB (Scolor, sName) {    this. Newmethod = ClassA;       This . Newmethod (Scolor);     Delete  This . Newmethod;     this. Name = sName;      This function () {        alert (this. name);}    ;}

To prove that the preceding code is valid, you can run the following example:

var New ClassA ("Blue"); var New ClassB ("Red", "John"); Obja.saycolor ();     // output "Blue"objb.saycolor ();    // output "Red"objb.sayname ();        // output "John"

Object impersonation can implement multiple inheritance

Interestingly, the impersonation of an object can support multiple inheritance. In other words, a class can inherit multiple superclass classes. The multi-inheritance mechanism represented by UML is as follows:

For example, if there are two classes CLASSX and Classy,classz want to inherit these two classes, you can use the following code:

var New ClassA ("Blue"); var New ClassB ("Red", "John"); Obja.saycolor ();     // output "Blue"objb.saycolor ();    // output "Red"objb.sayname ();        // output "John"

Tiy

There is a drawback here, that if there are two classes CLASSX and classy have properties or methods with the same name, classy has a high priority. Because it inherits from the following class. In addition to this small problem, it is easy to use object impersonation to implement multiple inheritance mechanisms.

Due to the popularity of this inheritance method, the third edition of ECMAScript added two methods to the Function object, call () and apply ().

Call () method

The call () method is the most similar method to the Classic object impersonation method. Its first parameter is used as the object of this. Other parameters are passed directly to the function itself. For example:

function Saycolor (sprefix,ssuffix) {    this. Color + ssuffix);};  var New  = "Blue""The color is", "a very nice color indeed.");

In this example, the function Saycolor () is defined outside the object, and even if it does not belong to any object, it can also refer to the keyword this. The color property of the object obj is equal to blue. When the call () method is called, the first parameter is obj, stating that the This keyword value in the Saycolor () function should be given to obj. The second and third arguments are strings. They match the parameters Sprefix and Ssuffix in the Saycolor () function, and the last generated message "The color is blue, a very nice color indeed." will be displayed.

To use this method with an object that inherits from the mechanism, simply replace the assignment, call, and delete code for the first three rows:

function ClassB (Scolor, sName) {    //this.newmethod = ClassA;    // This.newmethod (color);    // delete this.newmethod;    Classa.call (this, scolor);     this. Name = sName;      This function () {        alert (this. name);}    ;}

Tiy

Here, we need to make the ClassA keyword this equal to the newly created ClassB object, so this is the first parameter. The second parameter, Scolor, is the only parameter for two classes.

Apply () method

The Apply () method has two parameters, the object used as the this and an array of arguments to pass to the function. For example:

function Saycolor (sprefix,ssuffix) {    this. Color + ssuffix);};  var New  = "Blue"new Array ("The Color is", "a very nice color indeed."));

This example is the same as the previous example, except that the Apply () method is now called. When the Apply () method is called, the first parameter is still obj, stating that the This keyword value in the Saycolor () function should be assigned to obj. The second parameter is an array of two strings, matching the parameters Sprefix and Ssuffix in the Saycolor () function, and the last generated message is still "The color is blue, a very nice color indeed.", will be displayed 。

The method is also used to replace the first three rows of the assignment, call, and delete code for the new method:

function ClassB (Scolor, sName) {    //this.newmethod = ClassA;    // This.newmethod (color);    // delete this.newmethod;    Classa.apply (Thisnew  Array (Scolor));     this. Name = sName;      This function () {        alert (this. name);}    ;}

Similarly, the first argument is still this, and the second argument is an array with only one value of color. You can pass the entire arguments object of ClassB as the second argument to the Apply () method:

function ClassB (Scolor, sName) {    //this.newmethod = ClassA;    // This.newmethod (color);    // delete this.newmethod;    Classa.apply (this, arguments);     this. Name = sName;      This function () {        alert (this. name);}    ;}

Tiy

Of course, a parameter object can be passed only if the order of the parameters in the superclass is exactly the same as the order of the parameters in the subclass. If not, you must create a separate array to place the parameters in the correct order. In addition, you can use the call () method.

Prototype chain (prototype chaining)

This form of inheritance was originally used for prototype chains in ECMAScript. The previous chapter describes how to define the prototype of a class. The prototype chain extends this way and implements the inheritance mechanism in an interesting way.

As I learned in the previous chapter, the prototype object is a template, and the object to instantiate is based on this template. In summary, any properties and methods of the prototype object are passed to all instances of that class. The prototype chain uses this function to implement the inheritance mechanism.

If you re-define the classes in the previous example in a prototype way, they will become the following form:

function= "Blue"function  () {    alert (this. color);}; function  New ClassA ();

The magic of prototyping is the highlighted blue line of code. Here, the prototype property of the ClassB is set to an instance of ClassA. This is interesting because you want to ClassA all of the properties and methods, but don't want to ClassB them one by one prototype property. Is there a better way than to give an instance of ClassA a prototype attribute?

Note: Call ClassA's constructor without passing parameters to it. This is standard practice in the prototype chain. Make sure that the constructor does not have any parameters.

Like an object impersonation, all properties and methods of a subclass must appear after the prototype property is assigned, because all methods that were assigned before it are deleted. Why? Because the prototype property is replaced with a new object, the original object that added the new method is destroyed. So, the code for adding the Name property and the Sayname () method to the ClassB class is as follows:

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

You can test this code by running the following example:

var New ClassA (); var New  = "Blue"= "Red"= "John"; Obja.saycolor (); Objb.saycolor (); Objb.sayname ( );

Tiy

In addition, in the prototype chain, the instanceof operator operates in a unique way. For all instances of ClassB, instanceof returns true for both ClassA and ClassB. For example:

var New  instanceof ClassA);    // output "true" instanceof ClassB);    // output "true"

This is an extremely useful tool in ECMAScript's weakly-typed world, but it cannot be used when impersonating an object.

The drawback of the prototype chain is that multiple inheritance is not supported. Remember that the prototype chain overrides the prototype property of the class with another type of object.

Blending mode

This inheritance uses constructors to define classes, not using any prototypes. The main problem with object impersonation is that the constructor must be used, which is not the best choice. However, if you use a prototype chain, you cannot use a constructor with parameters. How do developers choose? The answer is simple, both are used.

In the previous chapter, we explained that the best way to create a class is to define a property with a constructor and define the method with a prototype. This approach also applies to the inheritance mechanism, using the object to impersonate the inheritance constructor property, using the prototype chain to inherit the method of the prototype object. Rewrite the previous example in either of these ways, with the following code:

functionClassA (scolor) { This. color =Scolor;} ClassA.prototype.sayColor=function() {alert ( This. color);};functionClassB (Scolor, SName) {Classa.call ( This, Scolor);  This. Name =SName;} Classb.prototype=NewClassA (); ClassB.prototype.sayName=function() {alert ( This. name);};

In this example, the inheritance mechanism is implemented by two lines of highlighted blue code. In the code highlighted in the first line, in the ClassB constructor, the object is impersonating the Scolor property of the ClassA class. In the second line of highlighted code, the prototype chain inherits the method of the ClassA class. Because this hybrid uses the prototype chain, the instanceof operator can still run correctly.

The following example tests this piece of code:

var New ClassA ("Blue"); var New ClassB ("Red", "John"); Obja.saycolor ();     // output "Blue"objb.saycolor ();    // output "Red"objb.sayname ();    // output "John"


      • Inheritance mechanism instance
      • Advanced JavaScript Tutorials

Tiy

A detailed description of the call () method and the Apply () method

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.