2009-12-10 82 views
3

我想動態地調用一個對象內部的函數。找到apply函數,但沒有完全理解它。查看下面的代碼,觸發Test.checkQueue()它應該依次調用showSomething「方法」。謝謝。動態函數調用(應用)

var Test = {  
    , queue : [{action:'showSomething', id:'1234'},{action:'showOther', id:'456'}] 
    , showSomething: function(what) { 
     alert(what);  
    } 
    , checkQueue : function() { 
     console.log('checkQueue'); 
     console.log(this.queue); 
     if (this.queue.length) { 
      var do = this.queue.shift(); 
      console.log(do); 
      // action.action(action.id); 
      do.action.apply(this, do.id || []); 
     } 
    } 

}; 
+3

請記住'do'是一個*保留字*。 – CMS 2009-12-10 23:35:46

+0

'queue'前面的逗號是糟糕/草率的語法,它可能會破壞IE。 – 2009-12-10 23:39:12

+0

'做'改變。不要擔心賈斯汀逗號,這是一個節選。我更喜歡逗號的原因之一 - 更容易注意。 – 2009-12-11 15:32:40

回答

3

有(至少)兩個問題與您使用的apply這裏。

  1. 這是一個功能對象的一個​​方法,並且你似乎是調用它對字符串

  2. 它總是需要的陣列作爲其第二個參數 - 您正在傳遞在一個字符串或一空陣列。

嘗試調用它像這樣:

Test[do.action].apply(this, do.id ? [do.id] : []); 

使用Test[do.action]將訪問實際的功能,而不是字符串「showSomething」或「showOther」,並do.id ? [do.id] : []總是會返回一個數組。

+1

或者,OP可以使用'call'而不是'apply'來避免數組問題 – 2009-12-10 23:37:56

+0

感謝您的幫助。 – 2009-12-10 23:52:50

+0

實際上,由於函數調用是在一個對象實例('Test')上進行的,所以你不需要'應用'也不需要'調用',上下文('this'關鍵字)將被隱式地*設置在該函數上,沒有必要明確*設置它,例如。 '試驗[obj.action](obj.id);'。 – CMS 2009-12-11 00:37:30

2

問題是do.action是一個字符串,而不是函數。您可以通過以下兩種方式之一更改代碼。

  1. 而不是存儲在名隊列中的功能的,實際存​​儲功能:

    queue : [ { action: this.showSomething ... 
    

    您可能需要確保它已被定義第一或類似的東西,雖然。

  2. 解決的字符串返回實際的屬性:

    this[do.action].apply(...) 
    
+0

感謝幫助,我接受了第一篇文章,但我也可能會使用你的「this」,所以我不必硬編碼「class」的名字。 – 2009-12-10 23:53:31