Call, apply, and bind methods in Javascript

Source: Internet
Author: User
This article mainly analyzes call, apply, and bind methods in Javascript, and summarizes the connections and differences between call, apply, and bind methods at the end of this article, which has good reference value, let's take a look at it. The following content is divided into the following sections:

1. Source of the call/apply/bind method

2. Function. prototype. call ()

3. Function. prototype. apply ()

3.1: Find the maximum number in the array

3.2: Change the empty element of the array to undefined.

3.3: Convert objects similar to Arrays

4. Function. prototype. bind ()

5. Objects bound to the callback function

6. call, apply, and bind Methods

1. Source of the call/apply/bind method

First, when using the call, apply, and bind methods, we need to know where the three methods actually come from? Why are these three methods available?

The call, apply, and bind methods are inherited from Function. prototype and belong to the instance method.

console.log(Function.prototype.hasOwnProperty('call')) //trueconsole.log(Function.prototype.hasOwnProperty('apply')) //trueconsole.log(Function.prototype.hasOwnProperty('bind')) //true

In the above Code, true is returned, indicating that all three methods are inherited from Function. prototype. Of course, common objects, functions, and arrays all inherit the three methods in the Function. prototype object. Therefore, these three methods can be used in objects, arrays, and functions.

We will share with you the concept of inheritance later.

2. Function. prototype. call ()

The call method of the function instance can specify the point of this inside the function (that is, the scope of the function execution), and then call the function in the specified scope. The function is executed immediately.

Let's take a look at the example.

var keith = {rascal: 123};var rascal = 456;function a() {console.log(this.rascal);}a(); //456a.call(); //456a.call(null); //456a.call(undefined); //456a.call(this); //456a.call(keith); //123

In the code above, if the this keyword in function a points to a global object, 456 is returned. It can be seen that if the call method does not have a parameter, or the parameter is null, undefined, or this, it is equivalent to pointing to a global object. If you use the call method to direct this keyword to the keith object, that is, the function is executed in the scope of the keith object, and the returned result is 123.

The call () method can pass two parameters. The first parameter specifies the point of this in the function (that is, the scope of the function execution), and the second parameter is the parameter to be passed during function calling.

function keith(a, b) { console.log(a + b); }keith.call(null, 1, 2); //3

The first parameter is required. It can be null, undefined, and this, but cannot be null. If it is set to null or undefined, this indicates that the function keith is in the global scope. The second parameter must be added one by one. In the apply clause, it must be added as an array.

An Application of the call method calls the native method of the object. It can also be used to convert a class array object to an array.

var obj = {}; console.log(obj.hasOwnProperty('toString')); //false obj.hasOwnProperty = function() { return true; } console.log(obj.hasOwnProperty('toString')); //true console.log(Object.prototype.hasOwnProperty.call(obj, 'toString')); //false

In the above Code, hasOwnProperty is the method inherited by the obj object. If this method is overwritten, it will not get the correct result. The call method can solve this problem. It puts the original definition of the hasOwnProperty method on the obj object for execution, so that no matter whether there is a method with the same name on the obj, the result will not be affected. Note that hasOwnProperty is the native Object method of Object. prototype, and call is the method inherited from Function. prototype.

3. Function. prototype. apply ()

The apply method is similar to the call method. It also changes this point (the scope of the function execution) and calls the function in the specified scope. The function is also executed immediately. The only difference is that it receives an array as a parameter for function execution.

The first parameter of the apply method is also the object to which this points. If it is set to null, undefined, or this, it is equivalent to specifying a global object. The second parameter is an array. All the members of the array are used as parameters in sequence and the original function is input during the call. Parameters of the original function must be added one by one in the call method, but must be added as an array in the apply method.

Let's take a look at the nuances of call and apply.

function keith(a, b) { console.log(a + b); } keith.call(null, 2, 3); //5 keith.apply(null, [2, 3]); //5

In the code above, the first parameter is null, pointing to the global scope; the second parameter is passed in a slightly different form.

The apply method has the following applications.

3.1: Find the maximum number in the array

var a = [2, 4, 5, 7, 8, 10];console.log(Math.max.apply(null, a)); //10console.log(Math.max.call(null,2, 4, 5, 7, 8, 10)); //10 

In Javascript, the method for finding the maximum value in an array is not provided. In combination with the apply and Math. max methods inherited from Function. prototype, the maximum value of an array can be returned.

3.2: Change the empty element of the array to undefined.

Use the apply method to convert the empty elements of the Array into undefined by using the Array constructor.

Console. log (Array. apply (null, [1, 3]); // [1, undefined, 3]

The difference between empty elements and undefined is that the forEach method of the array skips empty elements, but does not skip undefined and null. Therefore, different results are obtained when traversing internal elements.

Var a = [1, 3]; a. forEach (function (index) {console. log (index); //, skipping the null element. }) Array. apply (null, ). forEach (function (index) {console. log (index); // 1, undefined, 3, set the empty element to undefined })

3.3: Convert objects similar to Arrays

In addition, the slice Method of the array object can be used to convert an object similar to an array (such as an arguments object) into a real array. Of course, an important application of the slice method is to convert objects similar to arrays into real arrays. Both call and apply can implement this application.

console.log(Array.prototype.slice.apply({0:1,length:1})); //[1]console.log(Array.prototype.slice.call({0:1,length:1})); //[1]console.log(Array.prototype.slice.apply({0:1,length:2})); //[1,undefined]console.log(Array.prototype.slice.call({0:1,length:2})); //[1,undefined]function keith(a,b,c){ return arguments; }console.log(Array.prototype.slice.call(keith(2,3,4))); //[2,3,4]

The parameters of the call and apply methods in the code above are all objects, but the returned results are all arrays, which means the object is converted into an array. From the code above, we can see that the premise of this method is that the processed object must have the length attribute and the corresponding number key.

4. Function. prototype. bind ()

The bind method is used to specify the internal point of this (the scope of execution) of the function, and then return a new function. The bind method does not execute a function immediately.

var keith = { a: 1, count: function() { console.log(this.a++); } }; keith.count(); //1 keith.count(); //2 keith.count(); //3

In the code above, if this. a points to the attribute inside the keith object, if this method is assigned to another variable, an error will occur during the call.

var keith = {a: 1,count: function() {console.log(this.a++);}};var f = keith.count;f(); //NaN

In the code above, if the count method is assigned to the f variable, the this object is no longer a keith object, but a window object. Window. a is undefined by default. After incremental calculation, undefined ++ equals NaN.

To solve this problem, you can use the bind method to bind this in the keith object to the keith object or call it directly.

var f = keith.count.bind(keith);f(); //1f(); //2f(); //3keith.count.bind(keith)() //1keith.count.bind(keith)() //2keith.count.bind(keith)() //3

Of course, this can also be bound to other objects.

var obj = {a: 100};var f = keith.count.bind(obj);f(); //100f(); //101f(); //102

Similarly, we can pass a parameter to the bind method. If the first parameter is null, undefined, or this, this object inside the function is directed to the global environment; the second parameter is required for the call, and the form of the passed parameter is the same as that of the call method.

function keith(a, b) {return a + b;}console.log(keith.apply(null,[1,4])); //5console.log(keith.call(null,1,4)); //5console.log(keith.bind(null, 1, 4)); //keith()console.log(keith.bind(null, 1, 4)()); //5

In the code above, we can see the difference between call, apply, and bind: the call and apply methods are executed immediately after the call. After the bind is called, the original function is returned and needs to be called again. It is a bit like a closure. If you are not familiar with the closure concept, you can read these two articles: deeply Understand javascript function parameters and closures, and talk about JavaScript closure functions.

5. Objects bound to the callback function

In this article, the description of the this keyword in javascript involves that if this object is used in the return function, this object will point to the DOM object, that is, the button object. To resolve this point in the callback function, use the following method.

Var o = {f: function () {console. log (this = o) ;}}$ ('# click '). on ('click', function () {o. f. apply (o); // or o. f. call (o); // or o. f. bind (o )();});

After you click the button, the console displays "true. Because the apply method (or call method) is not only bound to the object where the function is executed, but also executes the function immediately (the bind method is not executed immediately, pay attention to the difference ), therefore, you have to write the binding statement in a function.

6. call, apply, and bind Methods

In fact, this is used to specify the internal point of the function. These three methods are similar, but there are differences in form. You can use three methods to implement the above example.

To sum up the call, apply, bind methods:

A: The first parameter specifies the point of this in the function (the scope in which the function is executed), and then calls the function based on the specified scope.

B: All parameters can be passed during function calls. The call and bind methods need to be passed in directly, while the apply method needs to be passed in as an array.

C: call, The apply method is to execute the function immediately after the call, and the bind method is not executed immediately. You need to execute the function again. A bit of closure.

D: Changing the point of this object involves not only the call, apply, and bind methods, but also the that variable to fix the point of this. If you have any questions, please visit the this keyword in javascript For details

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.