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

array_of_functions[0];

That does not work as intended because each function in the array is executed when the array is created.

What is the proper way of executing any function in the array by doing:

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

Thanks!

Nick
  • 1,607
  • 2
  • 11
  • 4

22 Answers22

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

and then when you want to execute a given function in the array:

array_of_functions[0]('a string');
Darin Dimitrov
  • 1,023,142
  • 271
  • 3,287
  • 2,928
132

I think this is what the original poster meant to accomplish:

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

Hopefully this will help others (like me 20 minutes ago :-) looking for any hint about how to call JS functions in an array.

Min
  • 2,975
  • 1
  • 19
  • 24
pjcabrera
  • 1,458
  • 1
  • 9
  • 5
  • 4
    This is just what I needed, as it allows me to change the parameter calls, assuming my functions don't all take the same parameters :P – Jem Apr 16 '14 at 12:00
29

Without more detail of what you are trying to accomplish, we are kinda guessing. But you might be able to get away with using object notation to do something like this...

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

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

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

and to call one of them...

myFuncs.firstFunc('a string')
Jeff
  • 4,136
  • 23
  • 32
  • 3
    I think this is more developer friendly as we don't need to remember index of function. And also, If we want to push any function at the specific index then it causes change of index of all the functions next to it. So better use this – dd619 Aug 27 '18 at 11:10
19

I would complement this thread by posting an easier way to execute various functions within an Array using the shift() Javascript method originally described here

  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
  • 6,545
  • 4
  • 36
  • 39
17

Or just:

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

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

  thirdFunc: function(string) {
    // do something
  }
}
Robin
  • 21,667
  • 10
  • 62
  • 85
7

It's basically the same as Darin Dimitrov's but it shows how you could use it do dynamically create and store functions and arguments. I hope it's useful for you :)

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
    It is fine to add your answer no matter how many others there are. But it is preferable to add some explanation what is different/better about it than the others – Bowdzone Mar 12 '15 at 10:49
5

up above we saw some with iteration. Let's do the same thing using 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
  • 1,116
  • 2
  • 15
  • 24
  • The most accepted solutions basically worked, but despite actually calling the functions, JS kept throwing an error that the array name was not a function (and displaying that error in my visualizations). Your solution does not cause that error. Thank you. – AJK Dec 03 '21 at 20:07
2

Ah man there are so many weird answers...

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 is not supported by default, but there are libraries like ramda, lodash, or even redux which provide this tool

Daniel Tok
  • 207
  • 1
  • 9
1

This is 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);
Jesse
  • 8,605
  • 7
  • 47
  • 57
Leonardo Ciaccio
  • 2,846
  • 1
  • 15
  • 17
  • 1
    Are you sure that [this is the question](http://stackoverflow.com/q/4908378/1048572) which you wanted to answer on? It's not related. – Bergi May 12 '13 at 14:07
  • 1
    @Bergi Actually, it is. Replace the answer's `opera` with `array_of_functions` and you've got the same thing. How about now? – Jesse May 12 '13 at 14:22
  • @Jesse thanks, now i have a idea with post the code, this is my first response. – Leonardo Ciaccio May 12 '13 at 15:06
  • But OP had an array, while this is some object (with odd property names)? And what's the news of this answer, why not just upvote pjcabrera's or Robin's one? – Bergi May 12 '13 at 15:44
  • Robin write undefined element firstFunc;.... NO CORRECT, then "firstFunc";"secondFunc";.... – Leonardo Ciaccio May 23 '13 at 20:10
  • 1
    confusing name of variable. Thats not an array of functions but an object of functions – Craicerjack Apr 21 '16 at 14:26
1

If you're doing something like trying to dynamically pass callbacks you could pass a single object as an argument. This gives you much greater control over which functions you want to you execute with any parameter.

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
  • 3,058
  • 2
  • 20
  • 42
1

Execution of many functions through an ES6 callback

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

f(() => [
  console.log(1),
  console.log(2),
  console.log(3)
])
Thomas Gotwig
  • 3,659
  • 3
  • 17
  • 15
1

Using ES6 syntax, if you need a "pipeline" like process where you pass the same object through a series of functions (in my case, a HTML abstract syntax tree), you can use for...of to call each pipe function in a given array:

const setMainElement = require("./set-main-element.js")
const cacheImages = require("./cache-images.js")
const removeElements = require("./remove-elements.js")

let htmlAst = {}

const pipeline = [
    setMainElement,
    cacheImages,
    removeElements,
    (htmlAst) => {
        // Using a dynamic closure.
    },
]

for (const pipe of pipeline) {
    pipe(htmlAst)
}
Dharman
  • 30,962
  • 25
  • 85
  • 135
Steve Bauman
  • 8,165
  • 7
  • 40
  • 56
0

Maybe it can helps to someone.

<!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>
Jonathan Irwin
  • 5,009
  • 2
  • 29
  • 48
Hopkroft
  • 31
  • 4
0

A short way to run 'em all:

[first_function, ..., nth_function].forEach (function(f) {
    f('a string');
}); 
Danyal Aytekin
  • 4,106
  • 3
  • 36
  • 44
0

the probleme of these array of function are not in the "array form" but in the way these functions are called... then... try this.. with a 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] ); }

it work's here, where nothing upper was doing the job at home... hopes it will help

Quetzal
  • 1
  • 1
  • Could you explain why other answers don't work for you, and why yours does? Thank you! – Fabio says Reinstate Monica Oct 27 '16 at 16:25
  • it ever return me erors, undefined function, or they are precisly not evalued by javascript... (why i don't know, but this solved my problem) – Quetzal Oct 27 '16 at 18:54
  • 1
    Terrible advice. https://stackoverflow.com/questions/86513/why-is-using-the-javascript-eval-function-a-bad-idea – Andrei Savin Nov 03 '17 at 19:42
  • yes, terrible, as ever, but shot solution, and pretty easy to use especially if its far from an "input"... here it just solved an inner javascript impossibility in a short way... – Quetzal Nov 05 '17 at 15:52
0

Using 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
  • 516
  • 7
  • 12
0

I have many problems trying to solve this one... tried the obvious, but did not work. It just append an empty function somehow.

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

I solved it by using an array of strings, and later with eval:

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

for (var Func of array_of_functions) {
   eval(Func);
   }
Nezumi
  • 11
  • 3
0

maybe something like this would do the trick:

[f1,f2,f3].map((f) => f('a string'))

0

This answered helped me but I got stuck trying to call each function in my array a few times. So for rookies, here is how to make an array of functions and call one or all of them, a couple different ways.

First we make the array.

let functionsArray = [functionOne, functionTwo, functionThree];

We can call a specific function in the array by using its index in the array (remember 0 is the first function in the array).

functionsArray[0]();

We have to put the parenthesis after because otherwise we are just referencing the function, not calling it.

If you wanted to call all the functions we could use a couple different ways.

For loop

for (let index = 0; index < functionsArray.length; index++) {
  functionsArray[index]();
}

Don't forget the parenthesis to actually call the function.

ForEach ForEach is nice because we don't have to worry about the index, we just get handed each element in the array which we can use. We use it like this (non arrow function example below):

functionsArray.forEach(element => {
    element();
});

In a ForEach you can rename element in the above to be whatever you want. Renaming it, and not using arrow functions could look like this:

functionsArray.forEach(
    function(funFunctionPassedIn) {
        funFunctionPassedIn();
    }
);

What about Map? We shouldn't use Map in this case, since map builds a new array, and using map when we aren't using the returned array is an anti-pattern (bad practice).

We shouldn't be using map if we are not using the array it returns, and/or we are not returning a value from the callback. Source

Joshua Dance
  • 8,847
  • 4
  • 67
  • 72
0

I know I am late to the party but here is my opinion

let new_array = [
  (data)=>{console.log(data)},
  (data)=>{console.log(data+1)},
  (data)=>{console.log(data+2)}
]
new_array[0]
JellyFox
  • 35
  • 1
  • 1
  • 8
-1

you got some top answers above. This is just another version of that.

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

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

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

}

-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
  • 49
  • 1
  • 1
  • 5