“転送”を受け入れるJS関数の記述方法可変数のパラメーター?
-
06-07-2019 - |
質問
可変数のパラメーターを受け入れ、それらすべてのパラメーターを他の匿名関数に転送する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');