Call (), apply (), bind () and callback

Source: Internet
Author: User

1. Call (), apply (), bind () method

In JavaScript, call or apply is used instead of another object to invoke a method that changes the object context of a function from the initial context to the new object specified by Thisobj. The simple thing is to change the context of the function execution, which is the most basic usage. The basic difference between the two methods is the difference in the parameters of the communication.

    • Call (OBJ,ARG1,ARG2,ARG3); Call the first parameter to pass the object, which can be null. Parameters are separated by commas, and the parameters can be of any type.
    • Apply (OBJ,[ARG1,ARG2,ARG3]); Apply the first argument to an object, which can be an array or an arguments object.

1. Grammar
Let's take a look at the explanation of call in the JS manual:

Call Method
Invokes one method of an object, replacing the current object with another object.

call([thisObj[,arg1[, arg2[,   [,.argN]]]]])

Parameters

thisObj可选项。将被用作当前对象的对象。 arg1, arg2,  , arg可选项。将被传递方法参数序列。

Description
The call method can be used to invoke a method in place of another object. The call method can change the object context of a function from the initial context to a new object specified by Thisobj.

如果没有提供 thisObj 参数,那么 Global 对象被用作 thisObj。

To be clear is actually to change the object's internal pointer, that is, to change the object's this point to the content. This is sometimes useful in the object-oriented JS programming process.

2. Usage

Because function is also an object, each function contains two non-inherited methods: Apply () and call (). The purpose of both methods is to invoke the function in a specific scope, which is actually equivalent to setting the value of the This object in the function body. First, the Apply () method receives two parameters: one is the scope in which the function is run, and the other is the parameter array. Where the second argument can be an instance of an array, or it can be an arguments object. For example:

functionSum(NUM1, num2) {return num1 + num2;} function callSum1 (NUM1, num2) {return sum.apply (this, arguments); //incoming arguments object} function callSum2 (NUM1, num2) {return sum.apply (this, [Num1, num2 ]); //incoming array}alert (CALLSUM1 (10,10)); Span class= "Hljs-comment" >//20alert (callSum2 (10,10)); //20             
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

In the above example, CALLSUM1 () passes the this value when executing the sum () function (because it is called in the global scope, so the window object is passed in) and the arguments object. The callSum2 also calls the sum () function, but it passes in this and an array of arguments. Both functions perform correctly and return the correct results.

When you call a function without specifying an environment object in strict mode, the this value does not transition to window. Unless you explicitly add a function to an object or invoke apply () or call (), the This value will be undefined

3, different points

The call () method has the same effect as the Apply () method, and they differ only in the way that the parameters are received. For the call () method, the first parameter is the this value does not change, changing the rest of the parameters are passed directly to the function. In other words, when using the call () method, the arguments passed to the function must be enumerated individually, as shown in the following example.

function sum(num1, num2){    return num1 + num2;}function callSum(num1, num2){ return sum.call(this, num1, num2);}alert(callSum(10,10)); //20
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

In the case of the call () method, Callsum () must explicitly pass in each parameter. The result is no different from using apply (). Whether to use apply () or call () depends entirely on what kind of method you take to pass parameters to the function. If you intend to pass in the arguments object directly, or if you receive an array in a function, it is certainly more convenient to use apply (), otherwise it might be more appropriate to choose call (). (It doesn't matter which method to use without passing parameters to the function).

4. Scope of expansion function operation

In fact, passing parameters is not the real place to apply () and call (); their real strength is the ability to expand functions
The scope on which to run. Let's look at an example below.

"red";var o = { color: "blue" };function sayColor(){ alert(this.color);}sayColor(); //redsayColor.call(this); //redsayColor.call(window); //redsayColor.call(o); //blue
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

This example is modified on the basis of the example above that illustrates the this object. This time, Saycolor () is also defined as a global function, and when it is called in the global scope, it does display "red"-because the evaluation of This.color is converted to window.color evaluation. Saycolor.call (this) and saycolor.call (window) are two ways to explicitly call a function in the global scope, and the results will of course show "Red". However, when you run Saycolor.call (o), the execution environment of the function is different, because the this object in the function body points to O, and the result is "blue". The biggest benefit of using call () (or apply ()) to extend the scope is that the object does not need to have any coupling with the method.

In the first version of the previous example, we first put the Saycolor () function in the object o and then called it through O, and in the case of the rewrite here, the previous superfluous step is not required.

5. Bind () method

Finally, the bind () function, either call () or apply () is called immediately the corresponding function, and bind () does not, bind () will generate a new function, the bind () function parameter is consistent with call (), the first parameter is also tied The value of this, followed by an indeterminate argument passed to the function. The new function generated by bind () returns, when you want to tune it,

"red";var o = { color: "blue" };function sayColor(){ alert(this.color);}var objectSayColor = sayColor.bind(o);objectSayColor(); //blue
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

Here, Saycolor () calls bind () and passes in the object o, creating the Objectsaycolor () function. The This value of the Object-saycolor () function equals O, so you will see "blue" even if you call this function in the global scope.

Browsers that support the bind () method are ie9+, Firefox 4+, Safari 5.1+, Opera 12+, and Chrome.

2, call (), apply () inheritance and callback

Inheritance of Classes

First look at this example:

functionPerson(Name,age) {THIS.name = name;This.age=age;This.alertname =function() {Alert (THIS.name); }This.alertage =function () {alert (this.age); }}function webDever (name,age,sex) {Person.call (this,name,age); this.sex=sex; this.alertsex = functionthis.sex);}} var test= new webdever ("Fool's Wharf", 28, "Male"); Test.alertname (); //Fool Wharf Test.alertage (); //28test.alertsex (); //male              
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21st
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28

So that the Webdever class inherits the person class, and person.call (this,name,age) means that the person constructor (which is also a function) executes under the This object, then Webdever has all the properties and methods of the person, The test object is able to invoke the method and properties of the person directly

used for callbacks
Call and apply are also very useful in the number of callback rows, many times we need to change the execution context of the callback function in the development process, most commonly used such as AJAX or timing what, generally speaking, Ajax is the global, that is, the Window object, to see this example:

functionAlbum(ID, title, owner_id) {This.id = ID;this.name = title; this.owner_id = owner_id;}; Album.prototype.get_owner = function  (callback) {var self = this; $.get ( '/owners/' + this.owner_id,  function var album = new album (1, ' life ', 2) Album.get_owner (function this.name + ' belongs to ' + owner);});  
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21st
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31

Over here

album.get_owner(function (owner) {    alert(‘The album’ + this.name + ‘ belongs to ‘ + owner);});
    • 1
    • 2
    • 3
    • 4
    • 5

The THIS.name in the album object can be directly taken to the name attribute in the

3. Callback function

Speaking of the callback function, many people know the meaning, but still smattering. As for how to use, still a little confused. Some of the relevant online also did not elaborate on what is going on, said the more one-sided. I'm just saying a little bit of personal understanding, Daniel do not spray.

definition
What is a callback?
See Wiki's Callback_ (computer_programming) Entry:

In computer programming, a callback are a reference to a piece of executable code that's passed as an argument to other CO De.

In JavaScript, the callback function is specifically defined as: function A is passed as a parameter (function reference) to another function B, and this function B executes function A. Let's just say that function A is called a callback function. If there is no Name (function expression), it is called an anonymous callback function.

As an example:

你有事去隔壁寝室找同学,发现人不在,你怎么办呢?    方法1,每隔几分钟再去趟隔壁寝室,看人在不    方法2,拜托与他同寝室的人,看到他回来时叫一下你前者是轮询,后者是回调。那你说,我直接在隔壁寝室等到同学回来可以吗?可以啊,只不过这样原本你可以省下时间做其他事,现在必须浪费在等待上了。把原来的非阻塞的异步调用变成了阻塞的同步调用。JavaScript的回调是在异步调用场景下使用的,使用回调性能好于轮询。

So callback is not necessarily used for asynchrony, and callbacks are often used in scenarios where general synchronization (blocking) is required, such as executing a callback function after certain operations have been performed.

An example of using callbacks in a synchronous (blocking) purpose is to execute FUNC2 after the FUNC1 code execution is complete.

var func1=function(callback){    //do something. (callback && typeof(callback) === "function") && callback();}func1(func2); var func2=function(){}
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

Examples of asynchronous callbacks:

$(document).ready(callback);$.ajax({  "test.html",  context: document.body}).done(function() {   $(this).addClass("done");}).fail(function() { alert("error");}).always(function() { alert("complete"); });
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

When is the callback executed?

Callback functions, which are typically executed in a synchronous context, may not be executed in an asynchronous context because the event is not triggered or the condition is not satisfied. In addition, it is best to ensure that the callback exists and must be a function reference or function expression:

typeof(callback) === "function") && callback();
    • 1

Let's take a look at a rough definition of "function A has a parameter, which is a function B, and executes function B after function a finishes." Then this process is called a callback. The meaning of this sentence is that function B passes in function A as a parameter and executes it in order to execute a and then execute the parameter b,b is called a callback function. Let's look at the following example first.

   function  a(callback){      alert(‘a‘); callback.call(this);//或者是 callback(), callback.apply(this),看个人喜好 } function b(){ alert(‘b‘); } //调用 a(b);
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

The result is a pop-up ' a ' and then ' B '. So someone would ask, "What's the point of writing such a code?" It doesn't seem to have much effect! ”

Yes, I also think this is not the meaning of writing, "If you call a function directly inside the function call it is not OK." I'm just writing a small example for you to make a preliminary understanding. The process of actually writing code is rarely used in this way, because in most scenarios we pass parameters. Take a parameter:

function  c(callback){      alert(‘c‘); callback.call(this,‘d‘); }//调用c(function(e){ alert(e);});
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

This call does not seem familiar, here the e parameter is assigned to ' d ', we simply assign to the character channeling, in fact, can also be assigned to the object. Does jquery have an e parameter?

Use of callback functions

    • Resource loading: Execute callback after dynamically loading JS file, execute callback after loading IFRAME, Ajax operation Callback, image loading complete execution callback, Ajax and so on.

    • DOM events and node. JS events are based on a callback mechanism (the node. JS callback may have multiple layers of callback nesting issues).

    • SetTimeout delay Time is 0, this hack is often used, settimeout call function is actually a callback embodiment

    • Chained invocation: When chaining calls, it is easy to implement chained calls in the evaluator (setter) method (or in a method that does not have a return value in itself), and the accessor (getter) is relatively bad for chaining calls because you need the accessor to return the data you need instead of the this pointer. If you want to implement a chained method, you can use a callback function to implement

    • The function Call of SetTimeout, SetInterval, gets its return value. Since all two functions are asynchronous, that is, their call timing and the program's main process is relatively independent, so there is no way to wait for their return value in the body, they are opened when the program will not stop waiting, otherwise it will lose the meaning of settimeout and setinterval, So with return there is no point, only using callback. The meaning of callback is to notify the agent function of the result of the timer execution to deal with it in time.

When the implementation of a function is very lengthy, do you choose to wait for the function to finish processing, or to use a callback function for asynchronous processing? In this case, it becomes critical to use a callback function, such as an AJAX request. If the callback function is used for processing, the code can proceed with other tasks without having to wait. In practice, asynchronous calls are often used in JavaScript, and even here it is highly recommended!

The following is a more comprehensive example of using AJAX to load an XML file, and using the call () function to invoke a callback function in the context of the request object (requested objects).

functionFn(URL, callback) {var HttpRequest;Create xhr HttpRequest = window. XMLHttpRequest?New XMLHttpRequest (): window. ActiveXObject?New ActiveXObject ("Microsoft.XMLHTTP"):Undefined//functional detection for IE Httprequest.onreadystatechange = function () {if (httprequest.readystate = = =  Span class= "Hljs-number" >4 && httprequest.status = = = 200) { //State Judgment Callback.call (Httprequest.responsexml);} }; Httprequest.open ( "GET", url); Httprequest.send ();} FN ( "Text.xml", function () {//call function Console.log (this); //this statement after output});  Console.log ( "This would run before the above callback."); //this statement first outputs             
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21st
    • 22
    • 23

We request asynchronous processing, which means that when we start the request, we tell them to call our function when it's done. In fact, the onReadyStateChange event handler also takes into account the failure of the request, where we assume that the XML file exists and can be successfully loaded by the browser. In this example, the Async function is assigned to the onReadyStateChange event, so it is not executed immediately.

Finally, the second Console.log statement executes first, because the callback function executes until the request is complete.

Reprint http://blog.csdn.net/i10630226/article/details/49205355

Call (), apply (), bind () and callback

Related Article

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.