2

这件事几乎工程: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。我究竟做错了什么?谢谢。

+0

使用jQuery伟大的Ajax。 – sundowatch 2010-05-14 18:07:22

+1

欢迎在Stackoverflow :)而是使用4个空格而不是每个缩进的选项卡。然后,当你在这里复制代码时,你必须用另外4个空格缩进*完整*片段。你可以通过选择一块,然后按消息编辑器工具栏中的'010101'按钮或'Ctrl + K'键来完成。 – BalusC 2010-05-14 18:10:30

回答

4

它不起作用的原因是在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 blog post,但基本上是:当一个函数被调用不需要任何特别的努力,设置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,Prototype,Closure,其余几乎全部。

+0

开心的职位。非常感谢。 (也可以,嘿嘿。) – 2010-05-14 18:34:09

+0

@Radu:很好,这很有帮助。 (我注意到你在这里是新的:如果这回答了你的问题,请点击顶部附近答案左边的复选标记,这表示你的问题为“回答”,并将其视为正确答案。) – 2010-05-14 21:19:38

+0

@Radu:同意W/TJ像jQuery这样的Lib通过删除大量的管道代码实际上使得这更简单。请参阅:http://api.jquery.com/jQuery.ajax/ – 2011-01-13 03:06:09

相关问题