我创建了一个版本,其中包含与我的问题相关的所有内容:
//new version doesn't work ->
function global_function(server_response){}
function Constructor(global_function){
this.local_reference_to_global_function=global_function;}
Constructor.prototype.api_function(){
//this.localreference_to_global_function("test"); // works
//global_function("test"); // works
xmlhttp=XMLHttpRequest();
xmlhttp.onreadystatechange=function(){
this.local_reference_to_global_function(xmlhttp.responseText)}
// does not work on asynchronuous callback
// probably scope/visibility/closure lifetime/whatever is wrong
// and I need to understand what is wrong to fix it in my code .
// firebug said that "this.local_reference_to_global_function is not a function"
// the first 2 calls in this function work
//so I am puzzled that this doesn't
xmlhttp.open("GET",...);
xmlhttp.send();}
var derivativeConstructor;
function server_query(){
if(derivativeConstrucror===undefined){
var derivativeConstructor=new Constructor(global_function);}
derivativeConstructor.api_function();}
//old version works but clutters my code so I don't want it ->
//the actual code saves more lines of code
//and has better visibility
// so it's worth it
//unlike this example
function server_query(){xmlhttp=XMLHttpRequest();
xmlhttp.onreadystatechange=function(){
global_function(xmlhttp.responseText)}
xmlhttp.open("GET",...);
xmlhttp.send();} // this worked and all the rest should be practically unchanged
// where it all get's called from - should be unchanged between versions ->
<form action="" method="GET" onsubmit="(function(){return false;});">
<input type="button" value="TEST" onclick="server_query();">
</form>
当我说我要改变的旧版本的作品时,我的意思是。我的问题是我第一次没有发布我的整个代码,所以人们给人的印象是我没有先尝试,然后不再看我实际问的内容。 现在我也试图简化一些事情以消除我认为问题所在的地方的混乱,所以这不是实际的代码,可能无法在浏览器中粘贴复制 - 可能存在“小问题”。我只对我提出的问题感兴趣:我在哪里出错了函数可见性/闭包变量可见性/变量生命周期/无论我怎样修复它。
问题的旧版本:让我被烙印为没有通过回答/评论的2个人定义其功能的人 - &gt;
我有这个javascript代码应该简化服务器GET的创建:
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;}
Generic_server_request.prototype
.server_request=function(){
xmlhttp=new XMLHttpRequest();
xmlhttp.onreadystatechange=function(){
if(xmlhttp.readyState===4
&& xmlhttp.status===200)
this.client_callback_function(
xmlhttp.responseText);
else if((xmlhttp.status!==200) ||
xmlhttp.status===200 &&
xmlhttp.readyState!==2 &&
xmlhttp.readyState!==3)
alert("readystate "+xmlhttp.readyState
+" status "+xmlhttp.status);}
xmlhttp.open("GET",
this.server_location+
this.server_file+
this.query_parameters,
true);
xmlhttp.send();}
Generic_server_request.prototype
.set_query_parameters=function(query_parameters){
this.query_parameters=query_parameters}
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();}
问题是当服务器响应到来时,我在firebug控制台中得到了这个错误:“this.client_callback_function不是函数”。 我可以使用一些帮助来了解范围发生了什么。
编辑我有一个以前的版本,它完成了使用Generic ...和server_querry(输入)在之前版本的server_querry(输入)中应该实现的一切,而status_text在代码atm的其他部分运行正常,所以不是问题。并且使用server_status和server_status的代码不会修改以前的预期功能。此类内容也符合预期:
function Generic_server_request(...,client_callback_function){ ... this.client_callback_function = client_callback_function; client_callback_function( “测试”); //作品 this.client_callback_function( “测试”); //工作原理
答案 0 :(得分:1)
创建请求对象时,请使用:
new Generic_server_request(
"http://localhost/cgi-bin/",
"querry_handler.php",
status_text
);
但在构造函数中,您的函数描述为:
function Generic_server_request(
server_location,
server_file,
client_callback_function
)
因此,client_callback_function
代替status_text
传递{{1}}(不是函数)
答案 1 :(得分:0)
虽然我创造了另一个问题,但我解决了我的初始问题,但如果我没有新的建议,这对另一个问题有好处。 这是我目前相对于上面代码的通用外观的起点 (顶部代码块):
function global_function(server_response){}
function Constructor(global_function){
this.local_reference_to_global_function=global_function;}
//still doesn't work but now I intuitively get why it doesn't work
//apparently this.xmlhttp is created new instead of being the one in api_function
//and the 2 are not shared through the Constructor(global_function) environment
//I could use some help from someone that would tell me
//how to make minimal changes to get this.xmlhttp in this example
//(this.xmlhttp in prototype.callback and prototype.api_function)
//to reference the same object
//or make equivalent minimal changes to other parts of the code
Constructor.prototype.callback=function(){
this.xmlhttp.local_reference_to_global_function(this.xmlhttp.responseText);};
Constructor.prototype.api_function=function(){
this.xmlhttp=new XMLHttpRequest();
this.xmlhttp.onreadystatechange=this.callback();
//xmlhttp.onreadystatechange=function(){
// this.local_reference_to_global_function(xmlhttp.responseText)}
// old version accesses local_reference_to_global_function
// inside onreadystatechange function's new environment a new object
// which is where I was stumped initially
// new variable environment created that I didn't get
xmlhttp.open("GET",...);
xmlhttp.send();}
var derivativeConstructor;
function server_query(){
if(derivativeConstrucror===undefined){
var derivativeConstructor=new Constructor(global_function);}
derivativeConstructor.api_function();}