我有一个使用get
的简单XMLHttpRequest
函数,它接受一个回调参数。计划是在onload
事件处理程序上调用回调。
这是一个简化版本:
get(url,doit);
function doit(data) {
alert(data)
}
function post(url,callback) {
var xhr=new XMLHttpRequest();
xhr.onload=function() { // Version 1
callback(xhr.response)
}
xhr.onload=callback.bind(xhr,xhr.response); // Version 2
xhr.open('get',url,true);
xhr.send(data);
}
回调函数有一个参数data
,它应该是来自Ajax调用的响应。
我有两个版本的调用回调:
bind
来做同样的事情; this
设置为xhr
对象,xhr.response
作为参数发送。当我使用版本1时,一切都按预期工作。当我使用版本2时,data
参数为空。
我以为我知道XMLHttpRequest
和.bind()
相当不错,但我无法解释为什么第二个版本是空的。这里发生了什么(不)?
注释
感谢答案,我想我已经拥有了。
.bind()
会立即执行当前值xhr.responseText
,在此阶段,该值为空。
如果我需要回复 future 值,那么第一个版本似乎更合适。
谢谢大家。
答案 0 :(得分:1)
这是因为callback.bind
将立即执行。并且在执行时,xhr.responseText
显然不可用,因为请求尚未完成。您可以尝试这样来查看结果。
function doit(data) {
alert(data, this.responseText);
}
答案 1 :(得分:0)
这是bind
的行为:当参数绑定时,绑定值是引用的对象,或者当时的原始值。
这是一个简单的代码段:
function operate(callback) {
let a = {
display: 'AAA'
};
setTimeout(callback.bind('ThisObj', a.display), 1000);
a.display = 'AAA222';
}
operate(function(data) {
console.log(data);
});
打印结果为:AAA
,a.display
为绑定,a.display
为基本类型(String) - 绑定时刻的值(AAA
)通过了。
这就是xhr.response
发生的事情,因为它的类型是字符串。
但是,如果一个对象作为参数绑定,那么该对象的引用将被传递,这意味着绑定的函数将获得最新的值:
function operate(callback) {
let tmp = {
t: 'AAA'
};
let a = {
display: tmp
};
setTimeout(callback.bind('ThisObj', a.display), 1000);
tmp.t = 'AAA222';
}
operate(function(data) {
console.log(data);
});
打印结果为:{ t: 'AAA222' }
请注意:如果上例中的变量a
将其值更改为另一个对象,则绑定的参考值不会更改(仍然是之前引用的对象):
function operate(callback) {
let a = {
display: 'AAA'
};
setTimeout(callback.bind('ThisObj', a), 1000);
a = {
display: 'AAA222'
};
}
operate(function(data) {
console.log(data);
});
打印结果为:{ display: 'AAA' }