2009-10-25 86 views
6

如何編寫一個接受可變數量參數的Javascript函數,並將所有這些參數轉發給其他匿名函數?如何編寫接受和「轉發」可變數量參數的JS函數?

例如,假設觸發一個事件的方法的場景:

function fireStartedEvent(a,b,c,d,e,f,g,...) { 
    for(var i = 0; i < startedListeners.length; i++) { 
     startedListeners[i](a,b,c,d,e,f,g,...); 
    } 
} 

尤其是因爲我有一個事件工廠生成這些激勵方法,這些方法在知道有多少參數給定的沒有興趣事件或其處理程序消耗。所以我現在在7點硬連線(a到g)。如果它更少,沒有問題。如果它再次發生,它們會被切斷。我如何才能捕獲並傳遞全部參數?

謝謝。

(使用jQuery或任何其他JavaScript框架是不是一種選擇這裏。)

+0

是否可以傳遞參數和在JavaScript數組?這可以做到。 – Cyclone 2009-10-25 02:53:19

回答

8

解決這需要兩個JavaScript概念知識。

第一個是特殊的arguments局部變量,可以用來訪問函數參數而不知道它們的名字,它的工作原理就像一個數組。然而,arguments一個Array,但是「數組,如」 - 具有屬性命名0..n-1,其中n是函數的自變量數目和length屬性 - 對象。一個簡單的示範使用可能是:

function f (a) { // can include names still, if desired 
    // arguments instanceof Array -> false (exceptions to this?) 
    var firstArg = arguments[0] 
    // a === firstArg -> always true 
    // iterate all arguments, just as if it were an Array: 
    for (var i = 0; i < arguments.length; i++) { 
     alert(i + " : " + arguments[i]) 
    } 
} 
f("a","b","c") 

第二個特徵是Function.apply將調用的功能與特定的上下文(this當它被稱爲)與參數,從「陣列狀」的膨脹導致目的。 但參見

因此,將其組合在一起:

function fireStartedEvent() { 
    for(var i = 0; i < startedListeners.length; i++) { 
     // jQuery will often pass in "cute" things, such as a element clicked 
     // as the context. here we just pass through the current context, `this`, 
     // as well as the arguments we received. 
     var arg = Array.prototype.slice.call(arguments) 
     startedListeners[i].apply(this, args) 
    } 
} 

雖然ECMAScript規範只要求 「陣列狀」 對象,Function.apply普遍與 「陣列狀」 工作對象和一些常見的實現要求合適的Array對象。從Function.apply鏈接警告:

注:大多數瀏覽器,包括鉻14的Internet Explorer 9,仍然不接受陣列狀物體,並拋出一個異常[如果非數組對象已通過]。 [FireFox在第4版中修復。]

幸運的是,有一個相對簡單的成語打開「陣列狀」對象到一個Array(這是具有諷刺意味的,因爲Array.slice普遍與「陣列狀」對象工作):

var args = Array.prototype.slice.call(arguments); 

(然後args可以通用在Function.apply使用。)

+0

似乎不適用於提問者想要的東西。 – mauris 2009-10-25 03:09:50

+5

我想這*完全是*提問者想要的。 – bcat 2009-10-25 03:11:07

+0

謝謝,pst。您鏈接的文檔非常好。我把你的標記或勞裏的答案作爲已接受的答案之間的差距,因爲他花時間將它用於我原來的問題。這是一個硬幣折騰。我希望你明白。 – 2009-10-25 03:12:20

5

我認爲,「應用」和「論據」是兩個概念的JavaScript您可以使用此:

function fireStartedEvent() { 
    for (var i = 0; i < startedListeners.length; i++) { 
    startedListeners[i].apply(startedListeners[i], arguments); 
    } 
} 

下面是從我的Firebug控制檯一些代碼,我有試過了這一點:

a = function(foo) { alert('a: ' + foo); }; 
b = function(foo, bar) { alert('b: ' + foo + ', ' + bar); }; 

startedListeners = [a, b]; 

function fireStartedEvent() { 
    for (var i = 0; i < startedListeners.length; i++) { 
    startedListeners[i].apply(startedListeners[i], arguments); 
    } 
} 


fireStartedEvent('one', 'two'); 
+0

此代碼不正確。參數是類似數組的。這不是「一個數組」。 apply將一個數組作爲第二個參數。 – 2009-10-25 03:09:54

+0

pst,它似乎適用於我,因爲使用apply(null,arguments)調用的方法被調用並似乎識別所有不同的參數。我錯過了什麼問題嗎? – 2009-10-25 03:19:26

+0

@pst - 我不知道這個 - 你碰巧有一個例子,我發佈的函數不起作用? – 2009-10-25 03:21:22

相關問題