Several ways Javascript can call function methods

  • 2020-05-17 04:45:34
  • OfStack

The flexible syntax of javascript and the fact that there are 56 ways to implement the same functionality is not uncommon, along with some anti-human archetypal inheritance and asynchronous features, makes it even more confusing. I often don't know the difference between call and apply, so I'll make a note of it today so I don't forget it again.

In javascript, methods can be executed in the following ways:

1.func(), which is the most direct and common way of calling, also conforms to the thinking logic of people like 1, but has some deficiencies in some cases, which will be explained below.

2.(function(arg){})(window), anonymous method call, useful in constructing namespace, the parameters in the following parentheses correspond to the input parameter 11 in the anonymous method.

3. func.bind (sth)(), the mozilla manual mentions that bind is a new feature in ECMA-262 5th Edition, which is listed separately as a calling method because it compensates for the inability to bind scope in direct calls.

4. func.call (), which is the second invocation, each method has an call method defined in its prototype to execute the current method.

5.func.apply(), call's twin brother.

func()

This is the most common way to invoke it, and it can be found anywhere in any language. func(x, y) can pass in different parameters. In some languages, such as php, java, this call is sufficient to solve the one-slice problem. But javascript is a functional language, and the concept of closures and a strange keyword, this, determine the limitations of this invocation. this should be interpreted as the scope of the current code, it will change with the code execution to different pieces, but in some cases, we don't want this this be changed, such as binding on some dom event, we certainly don't want they called this were transferred to window objects, but sometimes that's true, for example the following code.


var a ={};
var func = function(x) {
    console.log(this);
};
a.onclick = function() {
    var x = 100;
    func(x);
};
a.onclick();

Think of a as a link on a page. Since we only want to bind the defined method to the onclick event, rather than calling it immediately, and because this method has one parameter, we need to wrap it up in an anonymous method and pass it to the onclick event of a. Here's a problem. this in func becomes a global object window, which we obviously don't want to be. At this point, the direct call of func() doesn't work, so we need to bind this outside func to the func method. So you have the bind,call,apply methods.

bind

The purpose of bind is very simple, returning the same method with an this object bound to it. The above code can be modified by 1 line to bind this on a object.


var a ={};
var func = function(x) {
    console.log(this);
};
a.onclick = function() {
    var x = 100;
    func.bind(this)(x);  // bind here
};
a.onclick();

In this way, the this of onclick will not run around like a chicken with its head cut off.

call & apply

call and apply are going to be in the first place, because they're so similar. They both support multiple parameters, and the first parameter is the this object to be bound. The second parameter is the difference between them. call USES a separate parameter as the input parameter of the calling method, and apply USES an array as the input parameter. Sometimes we don't want to change the this object, but want to manually bind it to another object. call and apply are very useful. (that's not to say you can't use bind, but it looks like bind was a bit late to the game and may not be compatible with the browser). Take a chestnut:


a = {
    func: function() {
              this.x += 1;
          },
    x: 0
};
b = {
    a: a,
    x: 20
};
for(var i = 0; i < 10; i++){
    b.a.func();
}
console.log(a.x);
console.log(b.x);

The above a and b objects have x, we hope func can modify the corresponding x, but the direct call can only modify x in func scope, that is, a.x. If you modify the code below 1, you can modify b.x


a = {
    func: function() {
              this.x += 1;
          },
    x: 0
};
b = {
    a: a,
    x: 20
};
for(var i = 0; i < 10; i++){
    b.a.func.call(b);  // bind this to b
}
console.log(a.x);
console.log(b.x);

This chestnut is poorly held and a bit far-fetched, and it's a very confusing style of code, with applicable scenarios, but not everywhere.


Related articles: