Come scrivere una funzione JS che accetta e & # 8220; inoltra & # 8221; numero variabile di parametri?
-
06-07-2019 - |
Domanda
Come posso scrivere una funzione Javascript che accetta un numero variabile di parametri e inoltra tutti quei parametri ad altre funzioni anonime?
Ad esempio, considera lo scenario di un metodo che genera un evento:
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,...);
}
}
Soprattutto dal momento che ho una fabbrica di eventi che genera questi metodi di fuoco, questi metodi non hanno interesse a sapere quanti parametri consumano un determinato evento o i suoi gestori. Quindi l'ho cablato a 7 in questo momento (da a a g). Se è inferiore, nessun problema. Se è più, vengono tagliati. Come posso semplicemente catturare e trasmettere tutti i parametri?
Grazie.
(L'uso di jQuery o di qualsiasi altro framework Javascript non è un'opzione qui.)
Soluzione
Risolvere questo richiede la conoscenza di due concetti JavaScript.
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")
La seconda funzione è Function.apply
che invocherà una funzione con un contesto specifico ( this
quando viene chiamato) con argomenti che derivano dalla espansione di una matrice " come " oggetto. Ma vedi 1 .
Quindi, mettendolo insieme:
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 Mentre la specifica ECMAScript richiede solo un array " come " object, Function.apply
non funziona universalmente con un array " come " oggetto e una serie di implementazioni comuni richiedono un oggetto Array
corretto. L'avviso dal link Function.apply
:
Nota: La maggior parte dei browser, tra cui Chrome 14 e Internet Explorer 9 , non accetta ancora array come oggetti e genererà un'eccezione [se non L'oggetto array è passato]. [FireFox è stato corretto nella versione 4.]
Per fortuna, esiste un linguaggio relativamente semplice per trasformare un array "quotato come" oggetto in un Array
(che è ironico perché Array.slice
funziona universalmente con un array " come " oggetto):
var args = Array.prototype.slice.call(arguments);
(E quindi args
può essere universalmente usato per essere utilizzato in Function.apply
.)
Altri suggerimenti
Penso che " applica " e "argomenti" sono due concetti JavaScript che puoi usare qui:
function fireStartedEvent() {
for (var i = 0; i < startedListeners.length; i++) {
startedListeners[i].apply(startedListeners[i], arguments);
}
}
Ecco un po 'di codice dalla mia console Firebug con cui l'ho provato:
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');