Home>

First, call (), apply (), bind () methods

Call or apply in javascript to call a method instead of another object,Changes the object context of a function from the original context to the new object specified by thisobj.Simply put, it changes the context in which the function is executed,This is the most basic usage.The basic difference between the two methods is the difference in passing parameters.

call (obj, arg1, arg2, arg3);call the first parameter passed to the object,Can be null. Parameters are passed by comma,The parameters can be of any type.

apply (obj, [arg1, arg2, arg3]);apply the first parameter to the object,The arguments can be arrays or arguments objects.

1.Syntax

First look at the explanation of call in the js manual:

call methodCall a method of an object,Replace the current object with another object.

call ([thisobj [, arg1 [, arg2 [, [, .argn]]]]])

parameter

thisobj is optional. The object to be used as the current object.

arg1, arg2,, arg are optional. A sequence of method parameters will be passed.

DescriptionThe call method can be used to call a method on behalf of another object.The call method changes the object context of a function from the original context to the new object specified by thisobj.

If the thisobj parameter is not provided, the global object is used as thisobj.

Note that white point is actually changing the internal pointer of the object,That is, change the content of this object.This is sometimes useful in object-oriented js programming.

2.Usage

Because functions are also objects,So each function contains two non-inherited methods:apply () and call (). The purpose of both methods is to call a function in a specific scope,It is actually equal to setting the value of this object in the function body.First, the apply () method takes two parameters:one is the scope in which the function is run,The other is an array of parameters.The second parameter can be an instance of array or an arguments object. E.g:

function sum (num1, num2) {
 return num1 + num2;
}
function callsum1 (num1, num2) {
 return sum.apply (this, arguments);//pass arguments object
}
function callsum2 (num1, num2) {
 return sum.apply (this, [num1, num2]);//pass array
}
alert (callsum1 (10,10));//20
alert (callsum2 (10,10));//20

In the example above,callsum1 () passed this as the this value when executing the sum () functionSo the window object) and arguments object are passed in. Callsum2 also calls the sum () function, but it passes in this and an array of parameters.Both functions execute normally and return the correct results.

In strict mode,Function is called without specifying an environment object,Then this value will not be converted to window. This value will be undefined unless you explicitly add the function to an object or call apply () or call ()

3. Differences

The call () method has the same effect as the apply () method.They differ only in the way they receive parameters.For the call () method,The first parameter is that the value of this has not changed,The change is that the remaining parameters are passed directly to the function.in other words,When using the call () method, the parameters passed to the function must be listed one by one,This is 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

In the case of using the call () method,callsum () must explicitly pass in every parameter.The result is no different than using apply ().As for whether to use apply () or call (), it all depends on which method you use to pass parameters to the function is most convenient.If you are going to pass in arguments object directly, or the first received in the containing function is also an array,Then using apply () is definitely more convenient;Otherwise, call () may be more appropriate.(Without passing parameters to the function,It doesn't matter which method you use).

4.Extend the scope of function operation

In fact, passing parameters is not the true place for apply () and call ();Where they are really powerful is the ability to extend functions

Scope on which to run.Let's look at an example.

window.color="red";
var o={color:"blue"};
function saycolor () {
 alert (this.color);
}
saycolor ();//red
saycolor.call (this);//red
saycolor.call (window);//red
saycolor.call (o);//blue

This example is modified from the previous example that explained this object.This time, saycolor () is also defined as a global function.And when it is called in the global scope,It does show "red"-because the evaluation of this.color is converted to the evaluation of window.color. While saycolor.call (this) and saycolor.call (window) are two ways to call functions explicitly in the global scopeThe result will of course show "red". However, when saycolor.call (o) is run, the execution environment of the function is different.Because the this object in the function body points to o, the result is "blue". Use call () (or apply ()) to maximize scope benefits,That is, the object does not need to have any coupling relationship with the method.

In the first version of the previous example,We first put the saycolor () function in object o, and then call it through o;And in the example rewritten here,There is no need for that extra step.

5.The bind () method

Finally, the bind () function. Whether it is call () or apply (), the corresponding function is called immediately.Whereas bind () does not, bind () generates a new function,The parameters of the bind () function are the same as those of call (). The first parameter is also the value of this to be bound. Later, it accepts indefinite parameters passed to the function. After the new function generated by bind () returns,Tune whenever i want,

window.color="red";
var o={color:"blue"};
function saycolor () {
 alert (this.color);
}
var objectsaycolor=saycolor.bind (o);
objectsaycolor ();//blue

Here, saycolor () calls bind () and passes in object o, creating the objectsaycolor () function. The this value of the object-saycolor () function is equal to o, so even if this function is called in the global scope,You will also see "blue".

Browsers that support the bind () method are ie9 +, firefox 4+, safari 5.1+, opera 12+, and chrome.

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

Class inheritance

First look at this example:

function person (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=function () {
 alert (this.sex);
 }
}
var test=new webdever ("Fool's Wharf", 28, "Male");
test.alertname ();//Fool's Wharf
test.alertage ();//28
test.alertsex ();//Male

In this way, the webdever class inherits the person class. The meaning of person.call (this, name, age) is to use the person constructor (also a function) to execute under this object.Then webdever has all the properties and methods of person,The test object can directly call person methods and properties

Used for callbackscall and apply are also very useful in the number of callback lines,Many times we need to change the execution context of the callback function during the development process,The most common ones are ajax or timing, etc.In general,ajax is global,That is, under the window object,Look at this example:

function album (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 (data) {
 callback &&callback.call (self, data.name);
 });
};
var album=new album (1, "Life", 2);
album.get_owner (function (owner) {
 alert ("the album" + this.name + "belongs to" + owner);
});

Here

album.get_owner (function (owner) {
 alert ("the album" + this.name + "belongs to" + owner);
});

This.name in can be directly taken to the name property in the album object.

Third, the callback function

Speaking of callback functions,Although many people know the meaning,But still a little understood.As for how to use it,Still a little confused.Some related ones on the Internet did not explain in detail what happened.It's more one-sided.Below I just talk about my personal understanding,Don't spray.

definition

What is a callback?

See the wiki's callback_ (computer_programming) entry:

in computer programming, a callback is a reference to a piece of executable code that is passed as an argument to other code.

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. We say that function a is called a callback function.If there is no name (function expression), it is called an anonymous callback function.

for example:

You have something to go to classmates in the bedroom next door,Found that the person was not there,What do you do?

Method 1, visit the bedroom next door every few minutes,See if people are

Method 2, please those who are in the same room with him,Call you when he sees back

The former is polling,The latter is a callback.

Then you say, can I just wait for my classmates to come back in the bedroom next door?

Yes, but this way you could save time doing other things,Now it must be wasted waiting.

Turn the original non-blocking asynchronous call into a blocking synchronous call.

JavaScript callbacks are used in asynchronous calling scenarios,Using callbacks is better than polling.

So callback is not necessarily used for asynchronous,Callbacks are often used in general synchronization (blocking) scenarios.For example, it is required to execute a callback function after performing certain operations.

An example of using callbacks in synchronization (blocking),The purpose is to execute func2 after the execution of func1 code is completed.

var func1=function (callback) {
 //do something.
 (callback &&typeof (callback) === "function") &&callback ();
}
func1 (func2);
 var func2=function () {
}

Example of asynchronous callback:

$(document) .ready (callback);
$.ajax ({
 url:"test.html", context:document.body
}). done (function () {
 $(this) .addclass ("done");
}). fail (function () {alert ("error");
}). always (function () {alert ("complete");
});

When is the callback executed

Callback,It is usually executed last in a synchronous situation.It may not be executed in an asynchronous situation,Because the event is not triggered or the condition is not met.In addition, it is best to ensure that the callback exists and must be a function reference or function expression:

(callback &&typeof (callback) === "function") &&callback ();Let's look at a rough definition "function a has a parameter,This parameter is a function b. Function b is executed after function a is executed. Then this process is called callback.", This means that function b is passed as a parameter to function a and executed. The order is to execute a first, and then execute the parameters b, b, which are the so-called callback functions.Let's look at the following example first.

function a (callback) {
 alert ("a");
 callback.call (this);/or callback (), callback.apply (this), depending on personal preference
 }
 function b () {
 alert ("b");
 }
 //transfer
 a (b);

As a result, "a" pops up first, then "b" pops up. It is estimated that someone will ask "what's the point of writing such code?It doesn't seem to have much effect!"

Yes, actually I do n’t think it ’s interesting to write it like this,"If you call a function, you can call it directly inside the function." I just write a small example for everyone,Do a preliminary understanding.It ’s rarely used in the process of actually writing code.Because in most scenarios,We are passing parameters.Here's a parameter:

function c (callback) {
 alert ("c");
 callback.call (this, "d");
 }
//transfer
c (function (e) {
 alert (e);
});

Does this call seem familiar?Here the e parameter is assigned the value "d", we simply assign the value to the character string,In fact, you can assign values ​​to objects.Does jquery also have an e parameter?

Use cases of callback functions

Resource loading:callback is executed after dynamic loading of js file,Execute callback after loading iframe,ajax operation callback,Callback after image loading is completed,ajax and more. dom events and node.js events are based on callback mechanisms (node.js callbacks may have multiple layers of callback nesting issues). The delay time of settimeout is 0. This hack is often used.The function called by settimeout is actually a reflection of a callback Chained calls:When chained,It's easy to implement chained calls in setter methods (or methods that don't return a value),The getter is relatively difficult to implement chained calls,Because you need the valuer to return the data you need instead of the this pointer, if i want to implement a chain method,Can be implemented with callback functions The function calls of settimeout and setinterval get their return values.Since both functions are asynchronous,That is:their calling sequence and the main flow of the program are relatively independent,So there is no way to wait for their return value in the body,The program will not stop waiting when they are opened,Otherwise, it will lose the meaning of settimeout and setinterval.So using return no longer makes sense,Only callbacks can be used. The significance of callback is to notify the proxy function of the result of timer execution for timely processing.

When the function implementation is very long,You choose to wait for the function to finish processing,Or use a callback function for asynchronous processing?In this situation,Using callback functions becomes critical,For example:ajax request. If you use a callback function for processing,The code can continue with other tasks,Without waiting.In actual development,Often use asynchronous calls in javascript,It is highly recommended even here!

Here is a more comprehensive example of loading xml files using ajax,And use the call () function, call the callback function in the context of the requested object (requested object).

function fn (url, callback) {
 var httprequest;//create xhr
 httprequest=window.xmlhttprequest?new xmlhttprequest ():
Window.activexobject?new activexobject ("microsoft.xmlhttp"):undefined;
 //Functional test for ie
 httprequest.onreadystatechange=function () {
 if (httprequest.readystate === 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 outputs
});
console.log ("this will run before the above callback.");//This statement is output first

We request asynchronous processing,Means that when we start the request,Just tell them to call our function when they're done.In practice,The onreadystatechange event handler must also consider the case of a request failure,Here we assume that the xml file exists and can be successfully loaded by the browser.In this example,Asynchronous functions are assigned to the onreadystatechange event, so they do not execute immediately.

Finally, the second console.log statement is executed first,Because the callback function is not executed until the request is completed.

  • Previous The operating mechanism and principle of PHP (bottom)
  • Next Jsp programming method to get files and directories under the current directory and windows drive letter