这件事几乎有效:

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);
}

} // 我的课

所以它只不过是让 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);
    };

还有更多关于 this 管理在 这篇博文, ,但基本上:当一个函数被调用而没有做任何特别的努力来设置 this, this 函数内始终是全局对象(window, ,在浏览器上)。有两种方法可以设置 this 拨打电话时:

  1. 使用 Function#call (或者 Function#apply)就像我上面所做的那样,传入对象引用以用作 this 作为第一个参数。调用该函数并设置 this 无论你传入什么。和...之间的不同 #call#apply 是您提供更多参数传递给函数的方式。和 #call 你将它们作为进一步的论据提供给 #call 致电(例如 func.call(thisArg, arg0, arg1, arg2)),而与 #apply 您可以在第二个参数中将它们作为数组提供(func.apply(thisArg, [arg0, arg1, arg2])).
  2. 使用点符号:如果您有一个对象,该对象具有分配给它的函数的属性(例如您的 start 属性),通过使用对象实例、点和属性名称(this.start() 或者 foo.start(), 等)将调用该函数并设置 this 到调用中的对象实例。所以点符号有两个作用 完全不同 事物:查找属性并找到一个函数作为其值,并调用该函数,以便 this 在调用期间设置为对象。从字面上看就像: var f = obj.func; f.call(obj).

有点偏离主题,但是:除非有充分的理由,否则我不会重新发明这个轮子。有很多库可以简单地进行 XHR 调用。 jQuery, 原型, 关闭, ,以及几乎所有其他的。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top