javascript 类在内部调用 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);
}
} // myClass
所以它只不过是将 XMLHttpRequest 对象作为我的类的成员,而不是全局定义,并以传统方式调用它。然而,在我的connectionEvent回调函数中,“this”的含义丢失了,即使该函数本身的作用域位于myClass内。我还确保从 myClass 实例化的对象保持足够长的活动时间(在脚本中声明为全局)。
在我看到的所有使用 javascript 类的示例中,“this”在内部函数中仍然可用。对我来说,事实并非如此,即使我将函数放在外面并将其设为 myClass.prototype.connectionEvent。我做错了什么?谢谢。
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
它不起作用的原因是,在 Javascript 中,
this
完全由函数的调用方式来定义,而不是由函数的定义位置来定义。这与其他一些语言不同。要使
this
符合您的预期,您必须通过“绑定”它来明确地确保这一点:this 管理的更多信息//blog.niftysnippets.org/2008/04/you-must-remember-this.html" rel="noreferrer">这篇博文,但基本上是:当一个函数被调用而没有任何特别的努力时设置
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
属性),请使用对象实例、点和属性名称 (< code>this.start() 或foo.start()
等)将调用该函数并将this
设置为调用中的对象实例。因此,点分符号做了两件完全不同的事情:查找属性并找到一个函数作为其值,然后调用该函数,以便在调用期间将this
设置为该对象。称呼。从字面上看,它就像: var f = obj.func; f.call(obj)。有点偏离主题,但是:除非有充分的理由,否则我不会重新发明这个轮子。有很多库可以简单地进行 XHR 调用。 jQuery,原型, 关闭,以及几乎所有其他内容。
The reason it's not working is that in Javascript,
this
is defined entirely by how a function is called, not where it's defined. This is different than some other languages.To have
this
mean what you expect, you'd have to ensure that explicitly by "binding" it:There's more information about
this
management in this blog post, but basically: When a function is called without any particular effort made to setthis
,this
within the function will always be the global object (window
, on browsers). There are two ways to setthis
when making a call:Function#call
(orFunction#apply
) as I did above, passing in the object reference to use asthis
as the first parameter. That calls the function and setsthis
to whatever you passed in. The difference between#call
and#apply
is how you supply further arguments to pass into the function. With#call
you supply them as further arguments to the#call
call (e.g.func.call(thisArg, arg0, arg1, arg2)
), whereas with#apply
you supply them as an array in the second argument (func.apply(thisArg, [arg0, arg1, arg2])
).start
property), calling it by using the object instance, a dot, and the property name (this.start()
orfoo.start()
, etc.) will call the function and setthis
to the object instance within the call. So the dotted notation does two entirely distinct things: Looks up the property and finds a function as its value, and calls the function such thatthis
is set to the object during the call. Literally it's like:var f = obj.func; f.call(obj)
.Slightly off-topic, but: Barring a really good reason to, I wouldn't reinvent this wheel. There are lots of libraries out there to simply XHR calls. jQuery, Prototype, Closure, and nearly all the rest.