我有这段应该在Firefox 3.6上工作的代码。问题是这个变量。应该定义为STEP2并在STEP3上使用的xmlhttp就像STEP2和STEP3上的代码位于不同的变量环境中一样,尽管我希望server_request和callback_function中的两种用法指向下面定义的query_request_manager超对象中的相同成员对象。我还创建了类似的代码,在服务器响应时没有异步回调,按照我的意图工作。
function Generic_server_request(server_location, server_file, client_callback_function)
{
this.server_location = server_location;
this.server_file = server_file;
this.query_parameters = "";
this.client_callback_function = client_callback_function;
this.xmlhttp = undefined;
} // STEP1 should create xmlhttp as undefined
Generic_server_request.prototype.callback_function = function ()
{
if (this.xmlhttp.readyState === 4 // STEP3 ERROR this.xmlhttp is undefined
// I expected it to be the object defined at STEP2
// but it's not so according to firebug
// similar code without asynchronous callback
// seems to work as I expect it to : no undefined error
&& this.xmlhttp.status === 200)
{
this.client_callback_function(
this.xmlhttp.responseText);
}
else if (this.xmlhttp.status !== 200 || (this.xmlhttp.status === 200 && this.xmlhttp.readyState !== 2 && this.xmlhttp.readyState !== 3))
{
alert("readystate " + this.xmlhttp.readyState + " status " + this.xmlhttp.status);
}
};
Generic_server_request.prototype.server_request = function ()
{
this.xmlhttp = new XMLHttpRequest(); // STEP2 xmlhttp defined for use
this.xmlhttp.onreadystatechange = this.callback_function; // server callback to prototype.callback
this.xmlhttp.open("GET", this.server_location + this.server_file + this.query_parameters, true);
this.xmlhttp.send();
};
Generic_server_request.prototype.set_query_parameters = function (query_parameters)
{
this.query_parameters = query_parameters;
};
var query_request_manager;
function do_querry()
{
server_querry("test");
}
function server_querry(input)
{
if (query_request_manager === undefined)
{
query_request_manager = new Generic_server_request( // the definition
"http://localhost/cgi-bin/", "querry_handler.php", status_text);
}
query_request_manager.set_query_parameters("?input=" + input);
query_request_manager.server_request();
} // the usage
//end javascript
<input type="button" value="Enter" onclick="do_querry();" />
问题是这个分配:
this.xmlhttp.onreadystatechange = this.callback_function;
赋值由this定义的函数。Callback_function绑定到onreadystatechange,但没有将其范围绑定到query_request_manager(这意味着在执行回调时,它将绑定到全局范围,而不是您想要的对象)。要解决这个问题,可以使用委托函数:
this.xmlhttp.onreadystatechange = (function () {
var me = this;
return function () {
return me.callback_function.apply(me, arguments);
}
}).call(this);
试试这个:
var Generic_server_request = function(server_location, server_file, client_callback_function){
this.server_location = server_location;
this.server_file = server_file;
this.query_parameters = "";
this.client_callback_function = client_callback_function;
this.xmlhttp = undefined; // STEP1 should create xmlhttp as undefined
}
Generic_server_request.prototype.callback_function = function(){
if(this.xmlhttp.readyState === 4 && this.xmlhttp.status === 200){ // STEP3 ERROR this.xmlhttp is undefined
// I expected it to be the object defined at STEP2
// but it's not so according to firebug
// similar code without asynchronous callback
// seems to work as I expect it to : no undefined error
this.client_callback_function(this.xmlhttp.responseText);
} else if(this.xmlhttp.status!==200 || (this.xmlhttp.status===200 && this.xmlhttp.readyState!==2 && this.xmlhttp.readyState!==3)){
alert("readystate " + this.xmlhttp.readyState + " status " + this.xmlhttp.status);
}
};
Generic_server_request.prototype.server_request=function(){
this.xmlhttp = new XMLHttpRequest(); // STEP2 xmlhttp defined for use
this.xmlhttp.onreadystatechange = this.callback_function; // server callback to prototype.callback
this.xmlhttp.open("GET", this.server_location + this.server_file + this.query_parameters, true);
this.xmlhttp.send();
};
Generic_server_request.prototype.set_query_parameters = function(query_parameters){
this.query_parameters = query_parameters;
};
var query_request_manager;
function do_querry(){
server_querry("test");
}
function server_querry(input){
if(query_request_manager === undefined){
query_request_manager = new Generic_server_request("http://localhost/cgi-bin/", "querry_handler.php", status_text);
}
query_request_manager.set_query_parameters("?input=" + input);
query_request_manager.server_request();
}
<input type="button" value="Enter" onclick="do_querry();" />