The use of call in Javascript is quite tangled. It is difficult to determine whether you really understand it based on the document.
Call Method
Applied to: Function objects
Call a method of one object to replace the current object with another object.
Call ([thisobj [, arg1 [, arg2 [, [,. argn])
Parameters:
Thisobj
Optional. Will be used as the object of the current object.
Arg1, arg2, and argn
Optional. The method parameter sequence will be passed.
Note:
The call method can be used to call a method instead of another object. The call method can change the object context of a function from the initial context to the new object specified by thisobj. If the thisobj parameter is not provided, the global object is used as thisobj.
1. Basic understanding: Example 1
Customizes a class, which has the showtxt method to display the name value of the current object.
Create an object and its name value is equal to test1.
Use the call method to add the showtxt method of class1 class to the newly created object OBJ, that is, specify this in this. showtxt of class1 class as OBJ, so that obj has the showtxt method. Test1 is displayed ".
function Class1(){ this.showTxt = function(){alert(this.name)}}var obj = new Object();obj.name="test1"Class1.call(obj);obj.showTxt();//test1alert(obj.showTxt);//function(){alert(this.name)}
This example is easy to understand.
2. Let's take a deeper look.
Example 2:Create a class1 instance and ask the instance to call the showtxt method to return the name value of the instance. Because this implementation does not have the name value, the undefine is returned.
function Class1(){ this.showTxt = function(){alert(this.name)}}var class1 = new Class1();class1.showTxt();//undefinedalert(class1.showTxt);//function(){alert(this.name)}
Example 3:Next, add a name value to class1. Then, class1 calls the showtxt method and returns class1. This is because the name value is added to the class, so the Instance name is changed from undefine to class1.
Function class1 () {This. name = 'class1'; // Add the name value this. showtxt = function () {alert (this. name) }}var class1 = new class1 (); class1.showtxt (); // class1alert (class1.showtxt); // function () {alert (this. name )}
Example 4:Class1.call (OBJ. name, this. this in showtxt is replaced with OBJ, so it becomes obj. name = 'class1', so obj. showtxt returns class1.
Function class1 () {This. name = 'class1'; // Add the name value this. showtxt = function () {alert (this. name) }} function class2 () {This. name = 'class2';} var class2 = new class2 (); class1.call (class2); alert (class2.showtxt); // function () {alert (this. name)} class2.showtxt (); // class1
Example 5:If you add obj. Name = 'test1' after class1.call (OBJ);, test1 is entered in the final result. The cause is obvious.
Function class1 () {This. name = 'class1'; // Add the name value this. showtxt = function () {alert (this. name) }} function class2 () {This. name = 'class2';} var class2 = new class2 (); class1.call (class2); class2.name = 'test1'; // redefine obj. NAME value alert (class2.showtxt); // function () {alert (this. name)} class2.showtxt (); // test1
In the preceding example, call is an object instance. In the following example, replace the object instance with a function to see what changes will occur in the execution result.
3. Change the first parameter of the call method from an instance to a function.
Example 6:Class2 is a reference to a function object. When class1.call (class2) is executed, this in this. showtxt is replaced with class2. In this way, class2 has the showtxt method. When class2.showtxt () is executed, the value of class2.name is returned. Because class2 does not define the name value, undefined is returned.
In the class2 function, this. Name is the name value of the Instance created by class2, not class2.name. These two values sometimes confuse me.
function Class1(){ this.showTxt = function(){alert(this.name)}}function Class2(){ this.name = 'class2';}Class1.call(Class2);alert(Class2.showTxt);//function(){alert(this.name)}Class2.showTxt();//undefined
4. See the following example.
Example 7:Class1.showtxt. call (class2); class2 is returned because function () {alert (this. name)} This is specified as class2 by call and changed to alert (class2.name). Therefore, class2.
Alert (class2.showtxt) returns undefined, indicating that the class2.showtxt method is not defined.
function Class1(){ this.showTxt = function(){alert(this.name)}}function Class2(){ this.name = 'class2';}var class1 = new Class1();var class2 = new Class2();class1.showTxt.call(class2);//class2alert(class2.showTxt);//undefined
This error is prompted because the showtxt method is added to class2. If you add class1.call (class2) before this call, the call is OK.
Class1.call(class2);class2.showTxt();//class1
Example 8:In this example, undefined is returned.
function Class1(){ this.showTxt = function(){alert(this.name)}}function Class2(){ this.name = 'class2';}var class1 = new Class1();class1.showTxt.call(Class2);//undefinedalert(Class2.showTxt);//undefined
5. What if the call function does not contain this?
Example 9:
function add(a,b){ alert(a+b);}function sub(a,b){ alert(a-b);}add.call(sub,3,1);//4
4, add. call (sub,) is used as a substitute for this in the Add function during execution. However, because this is not used in add, the sub function is ignored directly, so the result is 4.
Therefore, the actual execution is as follows: 4 is returned.
function add(a,b){ alert(a+b);}add(3,1);//4
6. Good. Next, let's look at a weird form.
Example 10:
function f1(){ alert(1);}function f2(){ alert(2)}var f3 = f1.call;f1.call(f2);//1f3.call(f2);//2
F1.call (F2); it is easy to understand. If you do not understand the case above, but how do you understand f3.call (F2), 2 is returned. For convenience, the equivalent change is f1.call. call (F2), then we will find that the f1.call method actually calls F2, so how can F1 have the call method? Call and apply belong to a function. prototype method, which is implemented internally by the JavaScript engine. Because it belongs to function. prototype, each function object instance, that is, each method has a call,
Apply attribute.
To understand f1.call. Call (F2), we must first know how the call method is executed so that f1.call. Call (F2) can be executed.
Example 11:
Reference a method written by JK to implement call using apply:
Function jscall (othis) {// call var argsnew = []; for (VAR I = 1; I <arguments. length; I ++) {argsnew. push (arguments [I]);} return this. apply (othis, argsnew);} function. prototype. jscall = jscall;
Or abbreviated
Function jscall (othis) {// The jscall here is call var argsnew = []. slice. call (arguments, 1) return this. apply (othis, argsnew);} function. prototype. jscall = jscall;
In this way, a jscall with the same functions as call is obtained.
Next, we will build two functions: F1 and F2.
function f1(a){ alert([this,a,'f1']);}f1(11);//[object Window],11,f1function f2(a){ alert([this,a,'f2']);}f2(22);//[object Window],11,f2
Use jscall to replace this in F1 with F2
function f1(a){ alert([this,a,'f1']);}function f2(a){ alert([this,a,'f2']);}f1.jsCall(f2,11);//function f2(a){alert([this, a, "f2"]);},11,f1
The execution result shows that [Object window] is replaced with the F2 function.
Function jscall (othis) {// The jscall here is call var argsnew = []. slice. call (arguments, 1) return this. apply (othis, argsnew);} function. prototype. jscall = jscall; function F1 (a) {alert ([this, A, 'f1']);} function F2 (a) {alert ([this,, 'F2']);} f1.jscall. jscall (F2, 11); // 11, F2
When f1.jscall. jscall (F2, 11); is executed, 11, F2 is returned. Why is this result returned? The focus is :)
F1.jscall method:
Alert (f1.jscall); // return // function jscall (othis) {// var argsnew = []. slice. call (arguments, 1); // return this. apply (othis, argsnew );//}
Therefore, f1.jscall. jscall can be replaced with jscall. jscall to check the execution result.
Function jscall (othis) {// The jscall here is call var argsnew = []. slice. call (arguments, 1) return this. apply (othis, argsnew);} function. prototype. jscall = jscall; function F1 (a) {alert ([this, A, 'f1']);} function F2 (a) {alert ([this,, 'F2']);} jscall. jscall (F2, 11); // 11, F2
Next, analyze
During jscall execution, return this. this in apply (othis, argsnew); is replaced with F2, 11 is passed as the parameter (othis, argsnew), and f2.apply (11 );
Function jscall (othis) {// The jscall here is call var argsnew = []. slice. call (arguments, 1) return this. apply (othis, argsnew);} function. prototype. jscall = jscall; function F1 (a) {alert ([this, A, 'f1']);} function F2 (a) {alert ([this,, 'F2']);} f2.apply (11); // 11, F2
The returned result is the same as f1.jscall. jscall (F2, 11.
Let's look back.
function f1(){ alert(1);}function f2(){ alert(2)}var f3 = f1.call;f1.call(f2);//1f3.call(f2);//2
This makes it easy to understand f1.call. during call (F2) implementation, this in call is replaced by f2.call () by F2 during f1.call execution. Because F2 does not reference this, the execution result is 2.
f2.call()//2
Note that f1.call is a method, and F1 is a function object. The two are different in call.