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

相關問題