定义一个名为"ajax"的单例对象的代码:
var ajax = {};
ajax.getHttpRequest = function() {
if (window.XMLHttpRequest) {
return new XMLHttpRequest();
} else if (window.ActiveXObject) {
return new ActiveXObject("Microsoft.XMLHTTP");
}
};
ajax.load = function(url, handleFunc) {
this.httpRequest = this.getHttpRequest();
this.httpRequest.onreadystatechange = function() { // this refers to ajax
if (this.readyState === XMLHttpRequest.DONE) { // this refers to httpRequest
if (this.status === 200) {
handleFunc(this.responseText);
} else {
alert("The request unsucceeded.");
}
}
};
this.httpRequest.open("GET", url, true);
this.httpRequest.send();
};
然后便可这样使用:
ajax.load("test1.txt", function(responseText) {
console.log(responseText);
});
ajax.load("test2.txt", function(responseText) {
console.log(responseText);
});
使用单例对象ajax,先后打开了两个文件并分别处理。所有细节均在ajax这个对象中自行处理,用户代码只需简单地多次调用其load()方法即可。尽管看似单例模式,但其内部实际上每调用一次load()方法,便自动生成一个XMLHttpRequest的实例,这样便可确保多次调用时不相互影响XMLHttpRequest在生命周期中的各种状态。
ajax的load()方法内部还负责进行检查状态的脏活,检查完全后才将服务器返回的responseText传给调用者,这样调用代码就无需费心再做这种脏活了。
需特别注意的地方是,在同一个load()方法中,this关键词分别引用了不同的对象。上面的代码已分别做了注解。
this.httpRequest.onreadystatechange = function() { // this refers to ajax
因为这个语句出现在ajax.load()方法内,因此this是指ajax这个对象本身。而在第二个语句
if (this.readyState === XMLHttpRequest.DONE) { // this refers to httpRequest
this是指ajax对象的httpRequest属性变量。因为onreadystatechange是一个回调函数,当ajax在接收到服务器中信息后,其httpRequest的状态自动改变,并由httpRequest调用后面的匿名函数,因此在这个匿名函数中的this已经变为了调用者httpRequest. 这正是JavaScript不同于其他面向对象语言的地方,应时刻引起注意。
这样,这个ajax对象虽然简单,但使用起来非常便利。