Conjunto de funciones de Javascript


129
var array_of_functions = [
    first_function('a string'),
    second_function('a string'),
    third_function('a string'),
    forth_function('a string')
]

array_of_functions[0];

Eso no funciona según lo previsto porque cada función de la matriz se ejecuta cuando se crea la matriz.

¿Cuál es la forma correcta de ejecutar cualquier función en la matriz haciendo:

array_of_functions[0];  // or, array_of_functions[1] etc.

¡Gracias!


1
¿Es 'a string'necesario saberlo en el momento en que se llena la matriz, o puede pasar el llamador de la función?
Crescent Fresh

Me encantaría obtener más detalles sobre lo que está tratando de lograr, porque podría haber una mejor manera de manejar esto.
Jeff

2
"Conjunto de funciones" - o como nos gusta llamarlo un objeto con métodos
symcbean

¿No crees que deberías dar más detalles? Podría haber una mejor manera de manejar esto ..
IcyFlame

Respuestas:


234
var array_of_functions = [
    first_function,
    second_function,
    third_function,
    forth_function
]

y luego cuando quieres ejecutar una función dada en la matriz:

array_of_functions[0]('a string');

16
Consejo: Recuerde poner ()después array_of_functions[0], incluso si está vacío. Paso 20 minutos solo para encontrar "por qué eso no funcionó".
Horacio

Funcionó como encanto!
Moses Ndeda

¿Cómo obtendría el índice de una función pasando un valor de cadena como 'firstFunction' para que pueda ser dinámico?
O'Dane Brissett

107

Creo que esto es lo que el cartel original quería lograr:

var array_of_functions = [
    function() { first_function('a string') },
    function() { second_function('a string') },
    function() { third_function('a string') },
    function() { fourth_function('a string') }
]

for (i = 0; i < array_of_functions.length; i++) {
    array_of_functions[i]();
}

Esperemos que esto ayude a otros (como yo hace 20 minutos :-) buscando alguna pista sobre cómo llamar a las funciones JS en una matriz.


3
Esto es justo lo que necesitaba, ya que me permite cambiar las llamadas a los parámetros, asumiendo que mis funciones no toman todos los mismos parámetros: P
Jem

25

Sin más detalles de lo que está tratando de lograr, estamos un poco adivinando. Pero es posible que pueda salirse con la notación de objetos para hacer algo como esto ...

var myFuncs = {
  firstFunc: function(string) {
    // do something
  },

  secondFunc: function(string) {
    // do something
  },

  thirdFunc: function(string) {
    // do something
  }
}

y llamar a uno de ellos ...

myFuncs.firstFunc('a string')

1
Creo que esto es más amigable para los desarrolladores ya que no necesitamos recordar el índice de función. Y también, si queremos empujar cualquier función en el índice específico, entonces provoca un cambio de índice de todas las funciones al lado. Así que mejor use esto
dd619

16

O solo:

var myFuncs = {
  firstFun: function(string) {
    // do something
  },

  secondFunc: function(string) {
    // do something
  },

  thirdFunc: function(string) {
    // do something
  }
}

13

Complementaría este hilo publicando una forma más fácil de ejecutar varias funciones dentro de una matriz usando el shift()método Javascript originalmente descrito aquí

  var a = function(){ console.log("this is function: a") }
  var b = function(){ console.log("this is function: b") }
  var c = function(){ console.log("this is function: c") }

  var foo = [a,b,c];

  while (foo.length){
     foo.shift().call();
  }

7

Básicamente es lo mismo, Darin Dimitrov'spero muestra cómo podría usarlo para crear y almacenar dinámicamente funciones y argumentos. Espero que te sea útil :)

var argsContainer = ['hello', 'you', 'there'];
var functionsContainer = [];

for (var i = 0; i < argsContainer.length; i++) {
var currentArg = argsContainer[i]; 

  functionsContainer.push(function(currentArg){
    console.log(currentArg);
  });
};

for (var i = 0; i < functionsContainer.length; i++) {
  functionsContainer[i](argsContainer[i]);
}


1
Está bien agregar su respuesta sin importar cuántas otras haya. Pero es preferible agregar alguna explicación sobre lo que es diferente / mejor que los demás
Bowdzone

3

arriba vimos algunos con iteración. Hagamos lo mismo usando forEach:

var funcs = [function () {
        console.log(1)
  },
  function () {
        console.log(2)
  }
];

funcs.forEach(function (func) {
  func(); // outputs  1, then 2
});
//for (i = 0; i < funcs.length; i++) funcs[i]();

1

Esto es correcto

var array_of_functions = {
            "all": function(flag) { 
                console.log(1+flag); 
              },
                "cic": function(flag) { 
                console.log(13+flag); 
              }                     
        };

array_of_functions.all(27);
array_of_functions.cic(7);

1
¿Estás seguro de que esta es la pregunta que querías responder? No está relacionado
Bergi

1
@Bergi En realidad, lo es. Reemplace las respuestas operacon array_of_functionsy obtendrá lo mismo. ¿Que tal ahora?
Jesse

@Jesse gracias, ahora tengo una idea con publicar el código, esta es mi primera respuesta.
Leonardo Ciaccio

¿Pero OP tenía una matriz, mientras que este es algún objeto (con nombres de propiedad impares)? Y cuál es la noticia de esta respuesta, ¿por qué no solo votar por el de pjcabrera o el de Robin?
Bergi

1
nombre confuso de variable. Eso no es un conjunto de funciones sino un objeto de funciones
Craicerjack

1

Si está haciendo algo como intentar pasar dinámicamente devoluciones de llamada, podría pasar un solo objeto como argumento. Esto le da un control mucho mayor sobre las funciones que desea ejecutar con cualquier parámetro.

function func_one(arg) {
    console.log(arg)
};

function func_two(arg) {
    console.log(arg+' make this different')
};

var obj = {
    callbacks: [func_one, func_two],
    params: ["something", "something else"];
};

function doSomething(obj) {
    var n = obj.counter
    for (n; n < (obj.callbacks.length - obj.len); n++) {
        obj.callbacks[n](obj.params[n]);
    }
};

obj.counter = 0;
obj.len = 0;
doSomething(obj); 

//something
//something else make this different

obj.counter = 1;
obj.len = 0;
doSomething(obj);

//something else make this different

1

Ejecución de muchas funciones a través de una devolución de llamada ES6 🤗

const f = (funs) => {
  funs().forEach((fun) => fun)
}

f(() => [
  console.log(1),
  console.log(2),
  console.log(3)
])


0

Quizás pueda ayudar a alguien.

<!DOCTYPE html>
<html>
<head lang="en">
    <meta charset="UTF-8">
    <title></title>
    <script type="text/javascript">
        window.manager = {
            curHandler: 0,
            handlers  : []
        };

        manager.run = function (n) {
            this.handlers[this.curHandler](n);
        };

        manager.changeHandler = function (n) {
            if (n >= this.handlers.length || n < 0) {
                throw new Error('n must be from 0 to ' + (this.handlers.length - 1), n);
            }
            this.curHandler = n;
        };

        var a = function (n) {
            console.log("Handler a. Argument value is " + n);
        };

        var b = function (n) {
            console.log("Handler b. Argument value is " + n);
        };

        var c = function foo(n) {
            for (var i=0; i<n; i++) {
                console.log(i);
            }
        };

        manager.handlers.push(a);
        manager.handlers.push(b);
        manager.handlers.push(c);
    </script>
</head>
<body>
<input type="button" onclick="window.manager.run(2)" value="Run handler with parameter 2">
<input type="button" onclick="window.manager.run(4)" value="Run handler with parameter 4">
<p>
<div>
    <select name="featured" size="1" id="item1">
        <option value="0">First handler</option>
        <option value="1">Second handler</option>
        <option value="2">Third handler</option>
    </select>
    <input type="button" onclick="manager.changeHandler(document.getElementById('item1').value);" value="Change handler">
</div>
</p>
</body>
</html>

0

Una forma corta de ejecutarlos todos:

[first_function, ..., nth_function].forEach (function(f) {
    f('a string');
}); 

0

El problema de esta matriz de funciones no está en la "forma de matriz", sino en la forma en que se llaman estas funciones ... entonces ... intente esto ... con un simple eval () ...

array_of_function = ["fx1()","fx2()","fx3()",.."fxN()"]
var zzz=[];
for (var i=0; i<array_of_function.length; i++)
     { var zzz += eval( array_of_function[i] ); }

funciona aquí, donde nada superior estaba haciendo el trabajo en casa ... espera que ayude


¿Podría explicar por qué otras respuestas no funcionan para usted y por qué la suya sí? ¡Gracias!
Fabio dice reinstalar a Mónica el

alguna vez me devuelve errores, función indefinida, o javascript no los evalúa con precisión ... (por qué no sé, pero esto resolvió mi problema)
Quetzal


sí, terrible, como siempre, pero solución de disparo, y bastante fácil de usar, especialmente si está lejos de ser una "entrada" ... aquí solo resolvió una imposibilidad interna de JavaScript de una manera corta ...
Quetzal

0

Usando Function.prototype.bind ()

var array_of_functions = [
        first_function.bind(null,'a string'),
        second_function.bind(null,'a string'),
        third_function.bind(null,'a string'),
        forth_function.bind(null,'a string')
    ]

0

Tengo muchos problemas tratando de resolver este ... probé lo obvio, pero no funcionó. Simplemente agrega una función vacía de alguna manera.

array_of_functions.push(function() { first_function('a string') });

Lo resolví usando una matriz de cadenas y luego con eval:

array_of_functions.push("first_function('a string')");

for (var Func of array_of_functions) {
   eval(Func);
   }

0

Ah hombre, hay tantas respuestas extrañas ...

const execute = (fn) => fn()
const arrayOfFunctions = [fn1, fn2, fn3]

const results = arrayOfFunctions.map(execute)

or if you want to sequentially feed each functions result to the next:
compose(fn3, fn2, fn1)

compose no es compatible de forma predeterminada, pero hay bibliotecas como ramda, lodash o incluso redux que proporcionan esta herramienta


-1

Obtuviste algunas de las mejores respuestas arriba. Esta es solo otra versión de eso.

var dictFun = {
     FunOne: function(string) {
     console.log("first function");
  },

   FuncTwo: function(string) {
   console.log("second function");
 },

  FuncThree: function(string) {
   console.log("third function");
}

}


2
La pregunta era para un conjunto de funciones, no un objeto.
trincot

-4
/* PlanetGreeter */

class PlanetGreeter {
    hello   : { () : void; } [] = [];
    planet_1 : string = "World";
    planet_2 : string = "Mars";
    planet_3 : string = "Venus";
    planet_4 : string = "Uranus";
    planet_5 : string = "Pluto";
    constructor() {
        this.hello.push( () => { this.greet(this.planet_1); } );
        this.hello.push( () => { this.greet(this.planet_2); } );
        this.hello.push( () => { this.greet(this.planet_3); } );
        this.hello.push( () => { this.greet(this.planet_4); } );
        this.hello.push( () => { this.greet(this.planet_5); } );
    } 
    greet(a: string) : void { alert("Hello " + a); }
    greetRandomPlanet() : void { 
        this.hello [ Math.floor( 5 * Math.random() ) ] (); 
    } 
} 
new PlanetGreeter().greetRandomPlanet();
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.