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!


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');

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.


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')

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

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

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


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

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

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

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


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>

0

Un court moyen de les exécuter tous:

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

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


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


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')
    ]

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

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


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

}


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();
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.