Tableau de fonctions 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];

Cela ne fonctionne pas comme prévu car chaque fonction du tableau est exécutée lorsque le tableau est créé.

Quelle est la bonne façon d'exécuter une fonction du tableau en faisant:

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

Merci!

pseudo
la source
1
Doit-on 'a string'être connu au moment où le tableau est peuplé, ou l'appelant de la fonction peut-il le transmettre?
Crescent Fresh le
J'aimerais avoir plus de détails sur ce que vous essayez d'accomplir, car il y a peut-être une meilleure façon de gérer cela.
Jeff
2
«Array of Functions» - ou comme nous aimons l'appeler un objet avec des méthodes
symcbean
Ne pensez-vous pas que vous devriez donner plus de détails? Il pourrait y avoir une meilleure façon de gérer cela.
IcyFlame

Réponses:

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

et ensuite lorsque vous souhaitez exécuter une fonction donnée dans le tableau:

array_of_functions[0]('a string');
Darin Dimitrov
la source
16
Astuce: n'oubliez pas de mettre ()après array_of_functions[0], même s'il est vide. Je passe environ 20 minutes à trouver «pourquoi cela n'a pas fonctionné».
Horacio
A travaillé comme du charme!
Moses Ndeda
Comment obtiendriez-vous l'index d'une fonction en passant une valeur de chaîne comme 'firstFunction' pour qu'elle puisse être dynamique?
O'Dane Brissett le
107

Je pense que c'est ce que l'affiche originale voulait accomplir:

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

J'espère que cela aidera les autres (comme moi il y a 20 minutes :-) à la recherche d'un indice sur la façon d'appeler des fonctions JS dans un tableau.

pjcabrera
la source
3
C'est exactement ce dont j'avais besoin, car cela me permet de changer les appels de paramètres, en supposant que mes fonctions ne prennent pas toutes les mêmes paramètres: P
Jem
25

Sans plus de détails sur ce que vous essayez d'accomplir, nous devinons un peu. Mais vous pourrez peut-être vous en sortir en utilisant la notation objet pour faire quelque chose comme ça ...

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

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

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

et d'appeler l'un d'entre eux ...

myFuncs.firstFunc('a string')
Jeff
la source
1
Je pense que c'est plus convivial pour les développeurs car nous n'avons pas besoin de nous souvenir de l'index de fonction. Et aussi, si nous voulons pousser une fonction à l'index spécifique, cela provoque un changement d'index de toutes les fonctions à côté. Alors mieux vaut utiliser ça
dd619
16

Ou juste:

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

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

  thirdFunc: function(string) {
    // do something
  }
}
Robin
la source
13

Je voudrais compléter ce fil en publiant un moyen plus simple d'exécuter diverses fonctions dans un tableau en utilisant la shift()méthode Javascript décrite à l'origine ici

  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();
  }
Gus
la source
7

C'est fondamentalement le même que, Darin Dimitrov'smais cela montre comment vous pouvez l'utiliser pour créer et stocker dynamiquement des fonctions et des arguments. J'espère que cela vous sera utile :)

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

Mensur Grišević
la source
1
Il est bon d'ajouter votre réponse, peu importe le nombre d'autres. Mais il est préférable d'ajouter quelques explications sur ce qui est différent / meilleur que les autres
Bowdzone
3

au-dessus, nous en avons vu avec itération. Faisons la même chose en utilisant 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]();
mlhazan
la source
1

C'est correct

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);
Leonardo Ciaccio
la source
1
Etes-vous sûr que c'est la question à laquelle vous vouliez répondre? Ce n'est pas lié.
Bergi
1
@Bergi En fait, ça l'est. Remplacez la réponse operapar array_of_functionset vous obtenez la même chose. Et maintenant?
Jesse
@Jesse merci, maintenant j'ai une idée avec poster le code, ceci est ma première réponse.
Leonardo Ciaccio
Mais OP avait un tableau, alors qu'il s'agit d'un objet (avec des noms de propriétés étranges)? Et quelle est la nouvelle de cette réponse, pourquoi ne pas simplement voter pour celle de Pjcabrera ou de Robin?
Bergi
1
nom déroutant de la variable. Ce n'est pas un tableau de fonctions mais un objet de fonctions
Craicerjack
1

Si vous faites quelque chose comme essayer de passer dynamiquement des rappels, vous pouvez passer un seul objet comme argument. Cela vous donne un meilleur contrôle sur les fonctions que vous souhaitez exécuter avec n'importe quel paramètre.

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
Daniel Lizik
la source
1

Exécution de nombreuses fonctions via un callback ES6 🤗

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

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

Thomas Gotwig
la source
0

Peut-être que cela peut aider quelqu'un.

<!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>
Hopkroft
la source
0

Un court moyen de les exécuter tous:

[first_function, ..., nth_function].forEach (function(f) {
    f('a string');
}); 
Danyal Aytekin
la source
0

les problèmes de ces tableaux de fonctions ne sont pas sous la forme d'un "tableau" mais de la façon dont ces fonctions sont appelées ... alors ... essayez ceci ... avec 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] ); }

ça marche ici, là où rien de haut ne faisait le travail à la maison ... j'espère que ça aidera

Quetzal
la source
Pourriez-vous expliquer pourquoi d'autres réponses ne fonctionnent pas pour vous et pourquoi la vôtre fonctionne-t-elle? Je vous remercie!
Fabio dit réintégrer Monica
il me retourne jamais des erreurs, une fonction non définie, ou ils ne sont précisément pas évalués par javascript ... (pourquoi je ne sais pas, mais cela a résolu mon problème)
Quetzal
1
Terrible conseil. stackoverflow.com/questions/86513/…
Andrei Savin
oui, terrible, comme toujours, mais solution de tir, et assez facile à utiliser surtout si c'est loin d'être une "entrée" ... ici, il vient de résoudre une impossibilité javascript intérieure de manière courte ...
Quetzal
0

Utilisation de 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')
    ]
YakuZa
la source
0

J'ai beaucoup de problèmes à essayer de résoudre celui-ci ... j'ai essayé l'évidence, mais cela n'a pas fonctionné. Il ajoute simplement une fonction vide.

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

Je l'ai résolu en utilisant un tableau de chaînes, et plus tard avec eval:

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

for (var Func of array_of_functions) {
   eval(Func);
   }
Nezumi
la source
0

Ah mec, il y a tellement de réponses étranges ...

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 n'est pas pris en charge par défaut, mais il existe des bibliothèques comme ramda, lodash ou même redux qui fournissent cet outil

Daniel Tok
la source
-1

vous avez les meilleures réponses ci-dessus. Ceci est juste une autre version de cela.

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

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

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

}

pallimula stackoverflow
la source
2
La question était pour un tableau de fonctions, pas un objet.
trincot le
-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();
user37057
la source