Details of the 4 call methods of JavaScript functions

  • 2020-03-30 02:39:48
  • OfStack

In JavaScript, a function is a first-class citizen, and a function is a data type in JavaScript, not just a module like C# or other descriptive languages. There are four modes of function invocation: function invocation, method invocation, constructor, and apply. Of all the invocation modes here, the main difference is the meaning of the keyword this, which is described below.

Main contents of this paper:

1. Analyze the four invocation forms of the function
2. Figure out the meaning of this in the function
3. Specify the process of constructor object
Learn to call functions using context

One, the form of function call

The function call form is the most common and best understood form. The so-called function form is the general declaration of the function after the direct call is. Such as:


//Declare a function and call it
function func() {
    alert("Hello World");
}
func();

Or:

//Use the function's Lambda expression to define the function and then call it
var func = function() {
    alert(" Hello, programmer ");
};
func();

Both of these pieces of code pop up a dialog box in the browser that displays the text in the string, which is the function call.

You can see that function calls are very simple, just like we've learned, but the key here is that in the function call mode, the key in the function refers to the global object, which in the browser is the window object. Such as:


var func = function() {
    alert(this);
};
func();

At this point, the dialog box pops up and prints out [object Window].

Method invocation pattern

The function call pattern is simple and is the most basic way to call it. But again, a function, once it's assigned to a member of an object, is different. When a function is assigned to a member of an object, it is no longer called a function, but a method. Such as:


//Define a function
var func = function() {
    alert(" I'm a function ?");
};
//Assign it to an object
var o = {};
o.fn = func; //Be careful not to put parentheses here
//  call 
o.fn();

In this case, o.f is a method, not a function. In fact, the method body of fn is exactly the same as func, but there is a subtle difference. Look at the following code:

//Contiguous code
alert(o.fn === func);
 The printout is true , this indicates that the two functions are the same thing, but modify the code of the function: 
//Modify the body of the function
var func = function() {
    alert(this);
};
var o = {};
o.fn = func;
//  To compare 
alert(o.fn === func);
//  call 
func();
o.fn();

The result here is that the two functions are the same, so the print is true. But because the calls to the two functions are different, the call to func prints [object Window], while the print result of o.f is [object object].

Here's the difference between a function call and a method call. In a function call, this refers to the global object window, while in a method, this refers to the current object, which in o.f refers to the object o.

Iii. Constructor invocation mode

Again, function, in pure function mode, this is window; In object method mode, this refers to the current object. In addition to these two cases, functions in JavaScript can also be constructors. The syntax for using a function as a constructor is to prefix the function call with a new keyword. Such as code:


//Define a constructor
var Person = function() {
    this.name = " The programmer ";
    this.sayHello = function() {
        alert(" Hello, this is " + this.name);
    };
};
//The constructor is invoked to create the object
var p = new Person();
//Using the object
p.sayHello();

The above example first creates a constructor, Person, and then USES the constructor to create the object p. New syntax is used here. The sayHello() method is then called with the object, which is the simpler case of creating an object using a constructor. As you can see from the case, this refers to the object itself. In addition to the simple use of the above, the function as a constructor has several changes, which are:

1. All the properties that need to be used by the object must be guided with this;

The meaning of the return statement of the function is overwritten. If it returns a non-object, it returns this.

This in the constructor

We need to analyze the process of creating an object to see what this means. As the following code:


var Person = function() {
    this.name = " The programmer ";
};
var p = new Person();

Here, the function Person is defined first, and now I will analyze the entire execution:

1. The program does not execute the body of the function at this point, so the JavaScript interpreter does not know the contents of the function.

2. Next, execute the new keyword, create the object, the interpreter opens up memory, get the reference of the object, and give the reference of the new object to the function.

3. Then execute the function and give the passed object reference to this. That is, in the constructor, this is the object that was just created by new.

Then add a member to this, that is, to the object.

5. At the end of the function, return this, and give this to the variable on the left.

After analyzing the constructor execution, you can conclude that this in the constructor is the current object.

Return in the constructor

The meaning of return changes in the constructor, first if in the constructor, if an object is returned, then keep the original meaning. If you return non-objects such as Numbers, booleans, and strings, return this. If you do not return a return statement, return this as well. See the following code:


//Returns the return of an object
var ctr = function() {
    this.name = " Zhao Xiaohu ";
    return {
        name:" Cattle deleterious "
    };
};
//Create an object
var p = new ctr();
//Accessing the name property
alert(p.name);

Execute the code, and the result printed here is "niang liang liang". Since an object is returned in the constructor, keep the meaning of return, return the object after the return, and look at the following code:

//Defines a constructor that returns non-object data
var ctr = function() {
    this.name = " Zhao Xiaohu ";
    return " Cattle deleterious ";
};
//Create an object
var p = new ctr();
//  use 
alert(p);
alert(p.name);

The result of the code running is that, first popover print [object object], then print "zhao xiaohu", because the return here is a string, belongs to the basic type, so the return statement here is invalid, return is this object, so the first print is [object object] and the second won't print undefined.

Apply invocation mode

In addition to the above three call patterns, functions also have the apply and call methods as objects. This is the fourth call pattern, which I call the apply pattern.

First, the apply pattern, which can be used either as a function or as a method, is a flexible way to use it. First look at the syntax: function name. Apply (object, parameter array);

Here, the syntax is more obscure, or use case to illustrate:

1. Create two new js files, "js1.js" and "js2.js";

2. Add code


//Js1. Js file
var func1 = function() {
    this.name = " The programmer ";
};
func1.apply(null);
alert(name);
//Js2. Js file
var func2 = function() {
    this.name = " The programmer ";
};
var o = {};
func2.apply(o);
alert(o.name);

3. Running two pieces of code respectively, you can find that the name attribute in the first file has been loaded into the global object window; The name attribute in the second file is in the incoming object o, meaning that the first corresponds to a function call and the second to a method call.

The parameters here are the parameters of the method itself, but they need to be stored in the form of an array, such as the code:


//An example of an array
var arr1 = [1,2,3,[4,5],[6,7,8]];
//Will it
var arr2 = arr1.conact.apply([], arr1);
 And then introduce Call mode . call  Patterns and The apply pattern The big difference is this  call  Parameters in the array, see the following code is clear: 
//Define methods
var func = function(name, age, sex) {
    this.name = name;
    this.age = age;
    this.sex = sex;
};
//Create an object
var o = {};
//Add members to the object
//The apply pattern
var p1 = func.apply(o, [" Zhao Xiaohu ", 19, " male "]);
//Call mode
var p2 = func.call(o, " Zhao Xiaohu ", 19, " male ");

In the above code, the result of the apply pattern is the same as that of the call pattern.

In fact, using the apply and call modes, you can arbitrarily control the meaning of this, which is widely used in the design mode of the function js. Simple the subtotal, js function calls in the four patterns, respectively is: functional, methods, constructors and apply. These patterns, the meaning of this: this is a global object in the function window, this refers to the current object in the method, in the constructor this object is created, in the apply mode this can be specified.. If null is used in apply mode, it is a function mode, and if an object is used, it is a method mode.

Comprehensive examples

Let's end with a case study. Case description: there is a div, id for dv, the mouse over the top to increase the height of 2 times, the mouse left to recover, directly on the js code below:


var dv = document.getElementById("dv");
var height = parseInt(dv.style.height || dv.offsetHeight);
var intervalId;
dv.onmouseover = function() {
    //Stops an animation that is already executing
    clearInterval(intervalId);
    //Get the target altitude
    var toHeight = height * 2;
    //Get the current object
    var that = this;
    //Start timer, change slowly
    intervalId = setInterval(function() {
        //I get my current height
        var height = parseInt(dv.style.height || dv.offsetHeight);
        //Record the steps that need to change each time
        var h = Math.ceil(Math.abs(height - toHeight) / 10);
        //Determine the change and stop the timer if the step size is 0
        if( h > 0 ) {
            //Why is that used here? Think about it
            that.style.height = (height + h) + "px";
        } else {
            clearInterval(intervalId);
        }
    }, 20);
};
dv.onmouseout = function() {
    //The principle is the same as before
    clearInterval(intervalId);
    var toHeight = height;
    var that = this;
    intervalId = setInterval(function() {
        var height = parseInt(dv.style.height || dv.offsetHeight);
        var h = Math.ceil(Math.abs(height - toHeight) / 10);
        if( h > 0 ) {
            that.style.height = (height - h) + "px";
        } else {
            clearInterval(intervalId);
        }
    }, 20);
};


Related articles: