Matrice di funzioni 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];

Ciò non funziona come previsto perché ogni funzione nell'array viene eseguita quando l'array viene creato.

Qual è il modo corretto di eseguire qualsiasi funzione nell'array eseguendo:

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

Grazie!


1
Deve 'a string'essere noto al momento del popolamento dell'array oppure il chiamante della funzione può passarlo?
Crescent Fresh,

Mi piacerebbe avere maggiori dettagli su ciò che stai cercando di realizzare, perché potrebbe esserci un modo migliore di gestirlo.
Jeff,

2
"Array of Functions" - o come ci piace chiamarlo un oggetto con metodi
symcbean

Non pensi che dovresti fornire maggiori dettagli? Potrebbe esserci un modo migliore per gestire questo ...
IcyFlame,

Risposte:


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

e quindi quando si desidera eseguire una determinata funzione nella matrice:

array_of_functions[0]('a string');

16
Suggerimento: ricorda di mettere ()dopo array_of_functions[0], anche se è vuoto. Trascorro 20 minuti solo per trovare "perché non ha funzionato".
Horacio,

Ha funzionato come un incanto!
Moses Ndeda,

Come otterresti l'indice di una funzione passando un valore di stringa come 'firstFunction' in modo che possa essere dinamico?
O'Dane Brissett,

107

Penso che questo sia ciò che il poster originale intendeva realizzare:

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]();
}

Spero che questo possa aiutare gli altri (come me 20 minuti fa :-) alla ricerca di qualche suggerimento su come chiamare le funzioni JS in un array.


3
Questo è proprio ciò di cui avevo bisogno, poiché mi consente di modificare le chiamate dei parametri, supponendo che le mie funzioni non prendano tutti gli stessi parametri: P
Jem

25

Senza ulteriori dettagli su ciò che stai cercando di realizzare, stiamo indovinando. Ma potresti essere in grado di cavartela usando la notazione oggetto per fare qualcosa del genere ...

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

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

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

e chiamarne uno ...

myFuncs.firstFunc('a string')

1
Penso che questo sia più adatto agli sviluppatori in quanto non è necessario ricordare l'indice di funzione. Inoltre, se vogliamo spingere qualsiasi funzione sull'indice specifico, allora provoca il cambio di indice di tutte le funzioni accanto ad esso. Quindi meglio usare questo
dd619

16

O semplicemente:

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

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

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

13

Completerei questa discussione pubblicando un modo più semplice per eseguire varie funzioni all'interno di un array usando il shift()metodo Javascript originariamente descritto qui

  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

È praticamente lo stesso Darin Dimitrov'sma mostra come usarlo per creare e archiviare dinamicamente funzioni e argomenti. Spero sia utile per te :)

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
Va bene aggiungere la tua risposta, non importa quanti altri ci siano. Ma è preferibile aggiungere alcune spiegazioni su cosa sia diverso / migliore rispetto agli altri
Bowdzone

3

sopra ne abbiamo visti alcuni con iterazione. Facciamo la stessa cosa usando forOach:

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

Questo è corretto

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
Sei sicuro che questa sia la domanda a cui vuoi rispondere? Non è collegato.
Bergi,

1
@Bergi In realtà lo è. Sostituisci la risposta operacon array_of_functionse hai la stessa cosa. Che ne dici adesso?
Jesse,

@Jesse grazie, ora ho un'idea con il post del codice, questa è la mia prima risposta.
Leonardo Ciaccio,

Ma OP aveva un array, mentre questo è un oggetto (con nomi di proprietà dispari)? E qual è la novità di questa risposta, perché non solo votare quella di Pjcabrera o di Robin?
Bergi,

1
nome confuso della variabile. Non è una serie di funzioni ma un oggetto di funzioni
Craicerjack,

1

Se stai facendo qualcosa come provare a passare dinamicamente i callback potresti passare un singolo oggetto come argomento. Questo ti dà un controllo molto maggiore su quali funzioni desideri eseguire con qualsiasi parametro.

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

Esecuzione di molte funzioni tramite un callback ES6 🤗

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

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


0

Forse può aiutare qualcuno.

<!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

Un modo breve per eseguirli tutti:

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

0

il problema di questi array di funzioni non è nella "forma dell'array" ma nel modo in cui queste funzioni sono chiamate ... quindi ... prova questo ... con un semplice 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] ); }

funziona qui, dove nulla di alto faceva il lavoro a casa ... spera che possa aiutare


Potresti spiegare perché le altre risposte non funzionano per te e perché le tue? Grazie!
Fabio dice di reintegrare Monica il

non mi restituisce mai errori, funzione indefinita, o non sono precisamente valutati da JavaScript ... (perché non lo so, ma questo ha risolto il mio problema)
Quetzal


sì, terribile, come sempre, ma soluzione di sparo, e abbastanza facile da usare soprattutto se è lontano da un "input" ... qui ha appena risolto un'impossibilità javascript interna in breve tempo ...
Quetzal

0

Utilizzo di 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

Ho molti problemi a provare a risolvere questo ... ho provato l'ovvio, ma non ha funzionato. Aggiunge semplicemente una funzione vuota in qualche modo.

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

L'ho risolto usando una serie di stringhe, e successivamente con eval:

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

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

0

Ah amico ci sono così tante risposte strane ...

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 non è supportato per impostazione predefinita, ma ci sono librerie come ramda, lodash o persino redux che forniscono questo strumento


-1

hai delle risposte migliori sopra. Questa è solo un'altra versione.

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 domanda era per una serie di funzioni, non per un oggetto.
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();
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.