Discussion on the scope of variables in JavaScript callback functions _javascript tips

Source: Internet
Author: User
Tags anonymous closure
1. Background
JavaScript in the callback function, I believe that everyone is not unfamiliar, the most obvious example is to do the AJAX request, provided by the callback function,
In fact, the event-handling method (Onclick,ondblclick, etc.) of the DOM node is also a callback function.
When using DWR, the callback function can appear as the first or last parameter, such as:
JScript code function CallBack (result) {} mydwrservice.dosomething (Param1,param2,callback); recommended by//dwr/or Mydwrservice.dosomething (CALLBACK,PARAM1,PARAM2);

2, the problem description
Recently, when using DOJO+DWR, I encountered a problem:
If the callback function is a method that belongs to an object (recorded as obj1), wait until DWR executes the callback function.
The context is not obj1.
The phenomenon of performance is that any property that accesses obj1 in a callback function is undefined.
Version: Dojo1.3.1 and DWR2
3, the code of the simulation problem
The following test code can simulate this problem:
JScript Code
Copy Code code as follows:

<script type= "Text/javascript" ><!--
var context= "global";
var testobj={
Context: "Initial",
Callback:function (str) {
callback function
Alert ("Callback: In the context in which I am in, context=" +this.context+ ", the way I was recalled:" +str);
}
};
Creates an object as the context of the test callback function
Testobj.context= "already set";
function Testcall () {
Callmethod (Testobj.callback);
Callobjmethod (Testobj,testobj.callback);
}
function Callmethod (method) {
Method ("Callback By default context");
}
function Callobjmethod (Obj,method) {
Method.call (obj, "Specify an explicit object context callback");
}
--></script>
<body> <a href= "javascript:void (0)" onclick= "Testcall ()" > Call Test </a> </body>

In the Callobjmethod method, I used two ways to recall the method:
The first: Method ("Callback By default context");
Without the specified context, we found that the value of the internal access contexts for the callback function is the value of the global variable.
This indicates that the default context in which the method is executed is the global context.
The second way: Method.call (obj, "Specify an explicit object context callback");
Specifies the context in which obj is executed, and can access the contexts within the object.

4. Research Dwr
Because 06 years using DOJO+DWR (1.0), has encountered this problem, did not do too much homework, directly changed the source code DWR.
Now with DWR2, I want to see if DWR has a new way of dealing with this problem,
Take the engine.js out of the Dwr.jar and view the relevant code for the callback (_remotehandlecallback and _execute).
It seems that the processing of callbacks is simpler than 1.0, and there is no way to pass objects and methods together.
5, to do further research
Because the use of this dwr in the project is too extensive, and I believe that such a demand should be satisfied, so did not immediately modify the source code,
First of all, search Dojo+dwr on Google, did not find any conclusions, perhaps dojo's users are not too much.
So I searched "JavaScript Callback object Context" and got an article specifically about Java callback functions:
Http://bitstructures.com/2007/11/javascript-method-callbacks
The most important sentence:
When a function is called as A to (Obj.alertval ()),
' This ' is bound to the object, it is called on (obj).
And when a function was called without an object (func ()),
The ' this ' is bound to the JavaScript global object (Windows in Web browsers.)
This article also provides a solution, using closure and anonymous methods,
In JavaScript, a closure is created automatically when a function is created inside a function.
This closure can remember the context at which the corresponding function was created.
So, if so:
JScript code var closurefunc=function () {testobj.callback ();}
So no matter where, it is equivalent to call Closurefunc () directly and call Testobj.callback ().
For more information, see the article mentioned above: Http://bitstructures.com/2007/11/javascript-method-callbacks.
6, improve the simulation code
Analog code only, we add one more callback mode:
JScript Code
Copy Code code as follows:

<script type= "Text/javascript" ><!--
var context= "global";
var testobj={
Context: "Initial",
Callback:function (str) {
callback function
Alert ("Callback: In the context in which I am in, context=" +this.context+ ", the way I was recalled:" +str);
}
};
Creates an object as the context of the test callback function
function Testcall () {
Callmethod (Testobj.callback);
Callwithclosure (function (param) {testobj.callback (param);});
Testobj.context= "already set";
Callobjmethod (Testobj,testobj.callback);
}
function Callmethod (method) {method ("callback By default context");}
function Callwithclosure (method) {method ("Keep context callback through closure");}
function Callobjmethod (obj,method) {method.call (obj, "Specify an explicit object context callback");
--></script>
<body> <a href= "javascript:void (0)" onclick= "Testcall ()" > Call Test </a> </body>

Testing the above code, we can see that the results are consistent through closure and by displaying the specified object.
7. Simulate a more realistic call scenario
But there is a problem with the above code, usually in the real world, if the callback function is the method in the object, then the method that initiates the request is also in the same object.
In JavaScript, this can also represent the current object, but it cannot be used directly in anonymous function, such as:
JScript code var testobj={context: "Initial", Callback:function (str) {//callback function alert ("Callback: In the contexts where I am, context=" + this.context+, "I was called back by the way:" +str); Caller:function () {callwithclosure (function (param) {this.callback (param);});};//create an object as the context of the test callback function
This in the code above refers not to the testobj, but to the global context.
You need to write a temporary variable outside closure to represent this, and the complete code is as follows:
JScript Code
Copy Code code as follows:

<script type= "Text/javascript" ><!--
var context= "global";
var testobj={
Context: "Initial",
Callback:function (str) {
callback function
Alert ("Callback: In the context in which I am in, context=" +this.context+ ", the way I was recalled:" +str);
},
Caller:function () {
Callwithclosure (function (param) {this.callback (param);});
var temp=this;
Callwithclosure (function (param) {temp.callback (param);});
}
};
Creates an object as the context of the test callback function
Testobj.context= "already set";
function Testcall () {
Callmethod (Testobj.callback);
Testobj.caller ();
Callwithclosure (function (param) {testobj.callback (param);});
Callobjmethod (Testobj,testobj.callback);
}

function Callobjmethod (obj,method) {method.call (obj, "Specify an explicit object context callback");
function Callmethod (method) {method ("callback By default context");}
function Callwithclosure (method) {method ("Keep context callback through closure");}
function Callback (str) {alert ("callback: I am a global function that is defined externally.) "); }
--></script>
<body>
<a href= "javascript:void (0)" onclick= "Testcall ()" > Call Test </a>
</body>

8, what is closure
Two one sentence summaries:
A closure is the local variables to a function-kept alive after the function has returned,
Or
A closure is a stack-frame which isn't deallocated when the function returns. (as if a ' stack-frame ' were malloc ' Ed instead of being on the stack!)

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.