2013-02-23 28 views
-1

所以今天我編寫了一個AJAX對象。試圖理解Prorotype和Lambda函數中的'this'

我創建了一個構造,ajaxObj:

function ajaxObj(arg1, arg2, wrapper) { 
      this.form = arg1; 
      this.btn = arg2; 
      this.msg = "Update successful"; 

      this.url = "process.php"; 
      this.wrap = wrapper; // this is the div the callback uses 

      this.serial = null; // serialized form for POSTing 

      this.callback = function() { 
        var div = document.createElement("div"); 
        div.innerHTML = this.msg; 
        div.setAttribute("id", "desiredID"); 
        this.wrap.appendChild(div); 

      } 

      this.btn.onclick = initXHR; 
    } 

有被實例指定頁面上型ajaxObj的幾個對象。我想包括不會改變,應在原型共享功能:

ajaxObj.prototype = { 
    constructor: ajaxObj, 

    makeXHR: function() { 
       // cross browser XHR code returns XHR obj 
    } 

    makeSer: function() { 
      this.serial = $(this.form).serialize(); 
    } 

    initXHR: function() { 
      // this is where shit gets weird! 
      this.makeSer(); // makeSer function doesnt exit 

      var http = this.makeXHR(); // makeXHR doesn't exist 

      http.onreadystatechange = function() { 
        /* this function checked for 
         http.status/http.readyState 
         and attempted to call this.callback() 
         which of course didn't exist. 

         I also tried to change instance 
         properties here which did not work */ 
      } 

      http.open("POST", this.url, true); /* this.url did not work 
                and had to be replaced 
                with "process.php" */ 
      http.setRequestHeaders("Content-Type","application/x..."); // TL;DT 
      http.send(this.serial) // <--- this works just fine??? 
    } 

我已經看了很多類似的問題,並在過去一週內給予了極大的時間和考慮到這一點。我現在有我的代碼,通過從構造函數中取回回調,以及通過取消原型的makeXHR()和makeSer(),並將它們全部放置在全局範圍中的全部

儘管我得到了我的代碼工作,我懊惱的是,我仍然不明白爲什麼this.url沒有內部xhr.open()工作,同時this.serial 工作xhr.send()


Bascally,爲什麼 '這個' 原型的一些地方的工作(如更換

ajaxObj.prototype = { 
............. 
    initXHR: function() { 
     makeSer(); 
     .... 
     http.open("POST", this.url, true); 
     .... 
     http.send(this.serial); 
     .... 
} 

ajaxObj.prototype = { 
    ............. 
     initXHR: function() { 
      this.serial = $(this.form).serialize(); 
      .... 
      http.open("POST", "process.php", true); 
      .... 
      http.send(this.serial); 
    } 

....請,未使我糊塗。我的印象是我想到了。在我使用var關鍵字時,在構造函數中設置this = this似乎不起作用,並且顯然(對於javascript,事情並不總是那麼明顯)刪除var關鍵字集合等於值使用最近的對象實例實例化。

回答

0

看看MDN's introduction to the this keyword。您可能稱爲「錯誤」功能,即不在ajaxObj實例上。向我們顯示該調用。

this.serial的工作原理和this.url的原因並不是您剛剛明確指定爲this.serial之前 - 雖然它可能不是您期望的對象的屬性。

+0

您的權利 - 和this.serial似乎不適用於頁面上的所有表單(其中有6個)。MDN是我的主頁。我讀了很多關於這個關鍵字,並進行了我自己的實驗,試圖理解它,但我會給這篇文章另一讀... – 2013-02-23 23:14:16

1

只要看看你的代碼,我可以看到你的initXHR函數只在你的目標按鈕的onclick觸發時被調用。如果你在initXHR中檢查這個,我相信你會發現它是你的按鈕。

我認爲,根據您目前的一流的設計,您將需要使用舊

var self = this; 

在你的構造,使您的initXHR特權函數(構造函數內)以訪問它。我已經評論了下面的代碼,告訴你我已經添加到你的ctor中。

function ajaxObj(arg1, arg2, wrapper) { 

    // Assign this -> self at the start of the func 
    var self = this; 

    this.form = arg1; 
    this.btn = arg2; 
    this.msg = "Update successful"; 

    this.url = "process.php"; 
    this.wrap = wrapper; 

    this.serial = null; 

    this.callback = function() { 
      var div = document.createElement("div"); 
      div.innerHTML = this.msg; 
      div.setAttribute("id", "desiredID"); 
      this.wrap.appendChild(div); 

    } 

    // Make initXHR a privileged function, ie. one that has 
    // access to private variables in ctor 
    this.initXHR = function() { 

     self.url // should be accessible here 
    } 

    this.btn.onclick = this.initXHR; // Assign it. 
} 
+0

謝謝,我確信我已經嘗試過......只有我離開了Prototype的initXHR,而不是把它放在構造函數中。這正是我想要做的。 順便說一句,完全脫離主題,我只是檢查Brendan Eich的網站,它看起來好像有一些很酷的東西在於JavaScript的未來:) – 2013-02-24 02:30:08

+0

我很高興幫助。我會在他的網站有一個香味,歡呼。 – 2013-02-24 11:47:52