Frage

Wie schreibe ich eine Javascript-Funktion, die eine variable Anzahl von Parametern akzeptiert und leitet alle diese Parameter zu anderen anonymen Funktionen?

Betrachten wir zum Beispiel das Szenario eines Verfahrens, das ein Ereignis ausgelöst wird:

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,...);
    }
}

Vor allem, da ich ein Ereignis Fabrik haben, die diese Feuer Methoden erzeugt haben diese Verfahren kein Interesse zu wissen, wie viele Parameter ein bestimmtes Ereignis oder seine Handler verbrauchen. So habe ich es bei 7 festverdrahtet jetzt (a bis g). Wenn es nicht weniger, kein Problem. Wenn es mehr ist, bekommen sie abgeschnitten. Wie kann ich nur erfassen und weitergeben alle Parameter?

Danke.

(jQuery oder anderen Javascript-Framework ist keine Option hier.)

War es hilfreich?

Lösung

Die Lösung dieses erfordert die Kenntnis von zwei JavaScript-Konzepte.

Die erste ist die besondere arguments lokale Variable, die sein kann verwendet, um die Funktionsargumente zuzugreifen, ohne ihren Namen zu kennen und es funktioniert wie ein Array. Allerdings arguments ist nicht ein Array, aber ist „Array wie“ - mit Eigenschaften genannt 0..n-1, wo n ist die Anzahl der Argumente der Funktion und einer length Eigenschaft - Objekt. Eine einfache Demonstration Nutzung könnte sein:

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

Das zweite Merkmal ist Function.apply denen aufrufen a Funktion mit einem bestimmten Kontext (this wenn sie aufgerufen wird) mit Argumenten, die von der Expansion führen von einem „Array wie“ Objekt. Aber sehen 1 .

So ist es die Zusammenstellung:

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 Während die ECMAScript-Spezifikation fordert nur für einen „Array wie“ Objekt, Function.apply nicht allgemein mit einem „Array wie“ arbeitet Objekt und eine Reihe von gemeinsamen Implementierungen erfordert ein richtiges Array Objekt. Die Warnung des Function.apply Link:

  

Hinweis: Die meisten Browser, einschließlich Chrome 14 und Internet Explorer 9 , nehmen noch nicht Array wie Objekte und eine Ausnahme [wenn eine nicht werfen Array-Objekt ist] übergeben. [FireFox wurde in Version 4 festgelegt.]

Zum Glück gibt es eine relativ einfach Idiom einen „Array wie“ Objekt in ein Array zu drehen (was ironisch ist, weil Array.slice hat allgemein mit einem „Array wie“ Objekt arbeitet):

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

(Und dann kann args universell in Function.apply verwendet werden, verwendet werden.)

Andere Tipps

Ich denke, „anwenden“ und „Argumente“ sind zwei JavaScript-Konzepte können Sie verwenden hier:

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

Hier ist ein Code aus meiner Firebug-Konsole ich das ausprobiert mit:

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');
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top