Cómo escribir una función JS que acepte y & # 8220; reenvía & # 8221; número variable de parámetros?
-
06-07-2019 - |
Pregunta
¿Cómo escribo una función de Javascript que acepta un número variable de parámetros y reenvía todos esos parámetros a otras funciones anónimas?
Por ejemplo, considere el escenario de un método que dispara 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,...);
}
}
Especialmente ya que tengo una fábrica de eventos que genera estos métodos de disparo, estos métodos no tienen interés en saber cuántos parámetros consume un evento determinado o sus manejadores. Así que lo tengo cableado a las 7 en este momento (de la A a la G). Si es menos, no hay problema. Si es más, se cortan. ¿Cómo puedo capturar y pasar todos los parámetros de todos ?
Gracias.
(El uso de jQuery o cualquier otro marco de JavaScript no es una opción aquí).
Solución
Resolver esto requiere el conocimiento de dos conceptos de 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 segunda función es Function.apply
que invocará una función con un contexto específico ( este
cuando se llama) con argumentos que resultan de la expansión de una matriz " como: " objeto. Pero vea 1 .
Así, juntándolo:
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 Mientras que la especificación ECMAScript solo solicita una matriz " como " objeto, Function.apply
no funciona universalmente con un " matriz como " El objeto y varias implementaciones comunes requieren un objeto Array
adecuado. La advertencia del enlace Function.apply
:
Nota: La mayoría de los navegadores, incluidos Chrome 14 y Internet Explorer 9 , aún no aceptan matrices como objetos y lanzará una excepción [si no es así. Se pasa el objeto de la matriz]. [FireFox se corrigió en la versión 4]
Afortunadamente, hay un modismo relativamente simple para convertir una matriz como " objeto en un Array
(lo cual es irónico porque Array.slice
funciona universalmente con un " matriz como " objeto):
var args = Array.prototype.slice.call(arguments);
(Y, a continuación, args
se puede usar universalmente como en Function.apply
.)
Otros consejos
Creo que " aplica " y " argumentos " Hay dos conceptos de JavaScript que puedes usar aquí:
function fireStartedEvent() {
for (var i = 0; i < startedListeners.length; i++) {
startedListeners[i].apply(startedListeners[i], arguments);
}
}
Aquí hay algo de código de mi consola Firebug. Probé esto con:
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');