Rad*_*u M 3 javascript properties class xmlhttprequest onreadystatechange
这件事几乎有效:
function myClass(url) {
this.source = url;
this.rq = null;
this.someOtherProperty = "hello";
// open connection to the ajax server
this.start = function() {
if (window.XMLHttpRequest) {
this.rq = new XMLHttpRequest();
if (this.rq.overrideMimeType)
this.rq.overrideMimeType("text/xml");
} else
this.rq = new ActiveXObject("Microsoft.XMLHTTP");
try {
this.rq.onreadystatechange = connectionEvent;
this.rq.open("GET", this.source, true);
this.rq.send(null);
this.state = 1;
} catch (err) {
// some error handler here
}
}
function connectionEvent() {
alert("i'm here");
alert("this doesnt work: " + this.someOtherProperty);
}
Run Code Online (Sandbox Code Playgroud)
} // 我的课
所以它只不过是将XMLHttpRequest对象作为我的类的成员而不是全局定义,并以传统方式调用它.但是,在我的connectionEvent回调函数中,"this"的含义丢失了,即使函数本身是在myClass中的作用域.我还确保我从myClass实例化的对象保持足够长的时间(在脚本中声明为全局).
在我看到的所有使用javascript类的例子中,"this"仍在内部函数中可用.对我来说,它不是,即使我把我的函数带到外面并使它成为myClass.prototype.connectionEvent.我究竟做错了什么?谢谢.
它不起作用的原因是在Javascript中,this完全由函数的调用方式定义,而不是定义它的位置.这与其他一些语言不同.
为了达到this你的期望,你必须通过"绑定"它来明确地确保它:
this.start = function() {
var self = this; // Set up something that survives into the closure
/* ...lots of stuff omitted... */
this.rq.onreadystatechange = function() {
// Call `connectionEvent`, setting `self` as `this` within the call
connnectionEvent.call(self);
};
Run Code Online (Sandbox Code Playgroud)
this在这篇博客文章中有更多关于管理的信息,但基本上是:当一个函数被调用而没有特别努力设置时this,this函数内将始终是全局对象(window在浏览器上).this拨打电话时有两种设置方式:
Function#call(或Function#apply)如上所述,传入对象引用以this用作第一个参数.它调用函数并设置this为传入的任何内容.#call和之间的区别在于#apply如何提供进一步的参数以传递给函数.与#call您提供它们作为进一步的参数给#call呼叫(例如func.call(thisArg, arg0, arg1, arg2)),而用#apply你提供它们作为一个阵列中的第二个参数(func.apply(thisArg, [arg0, arg1, arg2])).start属性),则使用对象实例,点和属性名称(this.start()或foo.start()等)调用该函数将调用该函数并设置this为调用中的对象实例.因此,虚线表示法有两个完全不同的东西:查找属性并查找函数作为其值,并调用this在调用期间设置为对象的函数.字面意思是:var f = obj.func; f.call(obj).稍微偏离主题,但是:除非有一个非常好的理由,否则我不会重新发明这个轮子.只有XHR调用有很多库.jQuery,Prototype,Closure,以及几乎所有其他内容.