“転送”を受け入れるJS関数の記述方法可変数のパラメーター?

StackOverflow https://stackoverflow.com/questions/1619850

質問

可変数のパラメーターを受け入れ、それらすべてのパラメーターを他の匿名関数に転送するJavaScript関数を作成するにはどうすればよいですか?

たとえば、イベントを発生させるメソッドのシナリオを考えます:

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)。それ以下であれば、問題ありません。それ以上の場合、彼らは切断されます。 all パラメータをキャプチャして渡すにはどうすればよいですか?

ありがとう。

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

役に立ちましたか?

解決

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

最初は特別な arguments ローカル変数。名前を知らなくても関数の引数にアクセスするために使用でき、配列のように機能します。ただし、 arguments Array ではなく、「array like」です; - 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")

2番目の機能は Function.apply は、&quot; array like&quot;の expansion の結果の引数を持つ特定のコンテキスト( this が呼び出されたとき)で関数を呼び出します。オブジェクト。 ただし、 1 を参照してください。

したがって、まとめます:

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

1 ECMAScript仕様では、「配列のような」のみを呼び出していますが、オブジェクト、 Function.apply は、「配列のような」では普遍的に動作しません。オブジェクトと多くの一般的な実装は、適切な Array オブジェクトを必要にします。 Function.apply リンクからの警告:

  

注: Chrome 14 Internet Explorer 9 を含むほとんどのブラウザは、オブジェクトのような配列を受け入れず、例外をスローします[配列オブジェクトが渡されます]。 [FireFoxはバージョン4で修正されました。]

ありがたいことに、「配列のような」を変える比較的単純なイディオムがあります。 Array へのオブジェクト( Array.slice は&quot; array like&quot;オブジェクトで普遍的に機能するため皮肉です):

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

(そして args は、 Function.apply で使用するために普遍的に使用できます。)

他のヒント

「適用」と思うおよび「引数」ここで使用できるJavaScriptの概念は次の2つです。

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');
ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top