将参数传递给匿名onreadystatechange回调的普通纯javascript(即非JQuery)方法是什么?
例如:
function doRequest(){
/* Get an XMLHttpRequest in a platform independent way */
var xhttp = getXmlHttpRequestObject();
var msg="show this message when done"; /* another variable to pass into callback */
/* How do I pass 'msg' and 'xhttp' into this anonymous function as locals
named 'x' and 'm'??? */
xhttp.onreadychangestate=function(x,m)
{
if( x.readyState == 4 )
{
alert(m);
}
}
/* do the open() and send() calls here.... */
}
答案 0 :(得分:32)
Javascript支持闭包,因此您编写的匿名函数将能够从封闭的xhttp
范围访问msg
和doRequest()
。
如果想明确地这样做(比如,如果你想在代码中的其他地方定义回调函数并重用它),你可以创建一个创建回调的函数。这也允许您使用不同的名称(例如x
和m
)对变量进行别名替换:
function createCallback(x, m) {
return function() {
/* Do whatever */
};
}
然后在doRequest()
中,执行xhttp.onreadystatechange = createCallback(xhttp, msg);
如果你想做的只是'重命名'变量,你可以内联和匿名进行:
xhttp.onreadystatechange = (function(x, m) {
return function() {
/* Do stuff */
}
})(xhttp, msg);
答案 1 :(得分:13)
上述部分答案对我不起作用。首先,对于没有参数的单独的callBack函数:
xhttp.onreadystatechange = callBack; //works; the function's NAME is required
现在假设修改了callBack函数以接收一些参数:
xhttp.onreadystatechange = callBack(x,m); //didn't work, and didn't know why
xhttp.onreadystatechange = createCallback(xhttp,msg); //bad part of above Answer
然而,在StackOverflow的其他地方,有人解释说它需要分配一个"函数引用"而不是"函数调用"到onreadystatechange(就像上面的NAME是一个函数引用),并发布了一个解决方案:
xhttp.onreadystatechange = function(){callBack(x,m);}; //works
我来到这里为其他答案添加了一些内容,但现在无法找到它。所以我不妨在这里添加它。在我自己的代码中,我使用了局部变量和全局变量,并发现了一些似乎无法正常工作的东西,但是现在我知道实际发生了什么,一个警告词似乎是合适的。假设" g"是一个全局变量:
xhttp.onreadystatechange = function(){callBack(x,g);};//anonymous function works
在某个时间点(T0)将函数引用分配给onreadystatechange,并在不同的时间(T1)调用callBack函数。那么,全局变量的价值" g"在T1处是传递给callBack函数的值,而不是" g"的值。在T0分配功能参考时。不要咬你这咬我! (局部变量通常没有这个问题,因为它们通常在T1范围之外,因此在设置匿名函数的参数值时,JavaScript必须在T0使用它们的现有值。)
答案 2 :(得分:5)
永远不会太晚! :-)
与其使用有些复杂的xhttp.onreadystatechange中的参数传递数据,还可以向xhr对象本身添加属性。
例如:
var m = "Hello!";
var xhttp = new XMLHttpRequest();
xhttp.m = m;
xhttp.onreadystatechange = function()
{
var x, m;
x = this;
m = x.m;
if ((x.readyState == 4) && (x.status == 200))
{
alert(m);
}
};
// ...