2009-10-25 5 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時にハードワイヤードにしている。もしそれがそれより少ないなら、問題はありません。それ以上あれば、彼らは途絶えます。どのようにキャプチャして渡すことができますすべてパラメータ?

ありがとうございました。

(jQueryのまたは任意の他のJavaScriptフレームワークを使用するには、ここではオプションではありません。)

+0

それはJavaScriptで配列としてパラメータを渡すことは可能ですか?それができます。 – Cyclone

答えて

8

が解決これは、2つのJavaScriptの概念の知識が必要です。

最初は特別なargumentsローカル変数で、関数の引数に名前を知らずにアクセスすることができ、それは配列のように機能します。しかし、argumentsないArrayが、「アレイ状」である - オブジェクト - n機能とlengthプロパティの引数の数である0..n-1名前特性を有します。簡単なデモの使用は、かもしれない:

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") 

第二の特徴は、「のようなアレイ」の膨張起因引数を持つ(それが呼び出されthis)特定のコンテキストを持つ関数を呼び出すFunction.applyありますオブジェクト。 しかし、を参照してください。

したがって、一緒にそれを置く:


ECMAScript仕様は、オブジェクトのみ "のようなアレイ" を求めているが

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) 
    } 
} 
Function.apply しないを普遍的 "のようなアレイ" と連携オブジェクトと多くの共通の実装 適切な Arrayオブジェクトを必要とします。

注:クローム14Internet Explorer 9の含むほとんどのブラウザは、まだオブジェクトのような配列を受け入れないと、非Arrayオブジェクト場合は、[例外をスローしますFunction.applyリンクからの警告合格]。 [FireFoxはバージョン4で修正されました。

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

ありがたいことに、比較的簡単に(Array.sliceは普遍的オブジェクト「のような配列」で動作しているため皮肉である)Arrayにオブジェクト「のような配列を」オンにするイディオムがあります

+0

は、質問者が望むものには適用されないようです。 – mauris

+5

これは、* ask *が* askerが望むものだと思います。 – bcat

+0

ありがとう、pst。リンク先のドキュメントが優れています。彼は私の元の質問にそれを適用する時間がかかりましたので、私はあなたまたはLauriの答えを受け入れられた答えとしてマーキングする間に引き裂かれました。それはコイン投げだった。ご理解頂けるとありがたいです。 –

5

私は、「適用」を考えると「引数が」あなたがここに使用できる2つのJavaScript概念である(そしてargsは普遍Function.applyで使用することで使用することができます。):

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は2番目のパラメータとして配列をとります。 –

+0

pst、apply(null、arguments)を使って呼び出されたメソッドが呼び出され、すべての個別の引数を認識するように見えるという点で、私にとってはうまくいくようです。私は行方不明の問題がありますか? –

+0

@pst - 私はこれを知らなかった - あなたが私が投稿した機能がうまくいかない例を持っているのですか? @Lauri Arg。 –

関連する問題