2011-06-11 57 views
15

錯誤這是我的代碼:JavaScript的「是不是一個函數」當調用定義的方法

request_xml: function() 
     { 
     http_request = false; 
        http_request = new XMLHttpRequest(); 
        if (http_request.overrideMimeType) 
          { 
          http_request.overrideMimeType('text/xml'); 
          } 
          if (!http_request) 
          { 
           return false; 
          } 
         http_request.onreadystatechange = this.response_xml; 
         http_request.open('GET', realXmlUrl, true); 
         http_request.send(null); 
         xmlDoc = http_request.responseXML; 

}, 



response_xml:function() 
    { 
     if (http_request.readyState == 4) 
     { 
      if(http_request.status == 404 && countXmlUrl<=3) 
      { 
       countXmlUrl++; 

       realXmlUrl = xmlUrl[countXmlUrl]; 
       this.request_xml(); 
      } 
      if (http_request.status == 200) 
      { 
       xmlDoc = http_request.responseXML; 
       alert("need to update3"); 
       this.peter_save_data(); 
      } 

     } 
    }, 

peter_save_data:function() 
    { 
// removed function code 
}, 

奇怪的是,警報火災沒有問題,但在函數調用下面給我這個錯誤:

Error: this.peter_save_data is not a function 

從其他函數調用相同的該死的函數在其他地方工作正常。

+4

我猜想那是因爲你在使用'this'在錯誤的範圍。你有沒有嘗試過將它傳遞給'peter_save_data()'函數,但將它稱爲'objWhatever.peter_save_data(this)'? – 2011-06-11 18:49:12

+0

這不是完整的代碼。缺少的一個重要難題是* how *'response_xml'被調用 - 這很重要,因爲它會改變'this'的含義(參見Jared的評論)。記住'this'可以被認爲是「方法調用的接收者」。 – 2011-06-11 18:52:10

+0

爲什麼不用合格的名稱來稱呼它? – 2011-06-11 18:52:23

回答

24

您可以在調用XML生成之前這樣做。

var that = this; 

後來......

that.peter_save_data(); 

因爲this通過使用新的函數變化範圍時勤換,你不能使用它訪問原始值。將其別名可以讓您仍然可以訪問這個的原始值。

+2

我會考慮一個潛在不必要的全局變量,這可能很難調試(例如,如果它已被別的東西使用或在別處設置,並且在方法完成時不清除)。 – 2011-06-11 18:56:15

+0

該變量不需要是全局的。它只需在上下文更改之前在本地進行聲明。 – 2011-06-11 19:01:35

6

缺失的一個重要難題是如何調用response_xml。這很重要,因爲它會改變this(參見Jared的評論)。

請記住,this可以被認爲是(大致)「方法調用的接收者」。如果response_xml被直接傳遞以用作回調,那麼當然它將不起作用 - this可能是window

考慮這些:

var x = {f: function() { return this }} 
var g = x.f 
x.f() === x // true 
g() === x  // false 
g() === window // true 

編碼愉快。


「修復」可能只是改變如何調用response_xml。有很多方法可以做到這一點(通常是關閉)。

例子:

// Use a closure to keep he object upon which to explicitly invoke the method 
// inside response_xml "this" will be "that", 
// which was "this" of the current scope 
http_request.onreadystatechange = (function (that) { 
    return function() { return that.response_xml() } 
}(this) 

// Or, alternatively, 
// capture the current "this" as a closed-over variable... 
// (assumes this is in a function: var in global context does not create a lexical) 
var self = this 
http_request.onreadystatechange = function() { 
    // ...and invoke the method upon it 
    return self.response_xml() 
} 

就個人而言,我只想使用jQuery或類似;-)

+0

編輯代碼以添加如何調用response_xml。 – Ryan 2011-06-11 18:58:03

+1

@Ryan更新瞭解決方案的答案;-) – 2011-06-11 18:58:51

+0

我投了你的評論,但對於像我這樣的新手它有點難以理解。雖然這兩種解決方案都在起作用,但我正在使用下面的一種(在我的腦海中更簡單),所以我已經接受了這個答案。希望你不要介意,希望我可以在這裏選擇兩個答案,謝謝! – Ryan 2011-06-11 19:05:46

-1

如果你想一類類似的行爲,使用正確的語法,使用該庫,是使用JSON將一個參數傳遞給一個使它不在其中的函數。

function MyClass(CTOR paarams){ 
    var response_xml=function() 
    { 
     if (http_request.readyState == 4) 
     { 
      if(http_request.status == 404 && countXmlUrl<=3) 
      { 
       countXmlUrl++; 

       realXmlUrl = xmlUrl[countXmlUrl]; 
       this.request_xml(); 
      } 
      if (http_request.status == 200) 
      { 
       xmlDoc = http_request.responseXML; 
       alert("need to update3"); 
       this.peter_save_data(); 
      } 

     } 
    } 

    var peter_save_data=function() 
    { 
     // removed function code 
    } 
} 

var Test = new MyClass(somthing,another_something); 
Test.response_xml(); 
//etc etc. 

或者,使用圖書館喜歡Moot,你可以做到這一點的JSON:

var T = new Class({ 
    response_xml:function() 
    { 
     if (http_request.readyState == 4) 
     { 
      if(http_request.status == 404 && countXmlUrl<=3) 
      { 
       countXmlUrl++; 

       realXmlUrl = xmlUrl[countXmlUrl]; 
       this.request_xml(); 
      } 
      if (http_request.status == 200) 
      { 
       xmlDoc = http_request.responseXML; 
       alert("need to update3"); 
       this.peter_save_data(); 
      } 

     } 
    }, 

    peter_save_data:function() 
    { 
     // removed function code 
    } 

}); 
var X = new T();//etc etc 
相關問題