57

i hope this question is not too simple, but i have no idea :(

How can i start a function with a var in the function name?

For example ...

my functions

function at_26();
function at_21();
function at_99();

start the function

var test_id = 21;   
at_'+test_id+'();   // doesn't work

I hope somebody can help me.

Thanks in advance! Peter

Manoj Govindan
  • 72,339
  • 21
  • 134
  • 141
Peter
  • 11,413
  • 31
  • 100
  • 152
  • 6
    Why do you need that? You could create a function called `at()` and pass your number to it as an argument. – jwueller Sep 17 '10 at 08:03

5 Answers5

98

Store your functions in an object instead of making them top level.

var at = {
    at_26: function() { },
    at_21: function() { },
    at_99: function() { }
};

Then you can access them like any other object:

at['at_' + test_id]();

You could also access them directly from the window object…

window['at_' + test_id]();

… and avoid having to store them in an object, but this means playing in the global scope which should be avoided.

Quentin
  • 914,110
  • 126
  • 1,211
  • 1,335
  • 6
    I'm more curious as to why someone would be creating 100 functions that differ by only an index... – colithium Sep 17 '10 at 08:28
  • 6
    Tests. Let's say you have a utilities library that does something like transform paths. You might have an array of paths to against which to test each method. This is an easy way to add utilities to the library without duplicating code to run the tests for each new method. – jonschlinkert Sep 10 '13 at 11:31
  • 1
    In my case, they don't. This is just an example of how they might differ. Some differ only in a slight handling requirement for the data being manipulated and it's much simpler to categorize them and use the category to jump between handlers. All sorts of interesting uses. – TheSatinKnight Oct 30 '17 at 02:30
  • @jonschlinkert In which case they should create an array of functions (the functions could even be anonymous) not hundreds of functions. See Express.js route/middleware definitions for how this **should** be done properly – slebetman Aug 06 '19 at 22:45
  • @colithium In my case, I can use this for "add", "multiply", "divide" etc . . . – Ac Hybl Nov 13 '22 at 23:43
28

You were close.

var test_id = 21
this['at_'+test_id]()

However, what you may want:

at = []
at[21] = function(){ xxx for 21 xxx }
at[test_id]()
JeanHuguesRobert
  • 696
  • 5
  • 10
2

You can also try

function at_26(){};
function at_21(){};
function at_99(){};

var test_id = 21;   
eval('at_'+test_id+'()'); 

But use this code if you have very strong reasons for using eval. Using eval in javascript is not a good practice due to its disadvantages such as "using it improperly can open your script to injection attacks."

Nik
  • 4,015
  • 3
  • 20
  • 16
  • 6
    No! Do not use `eval()` in this case! There are much better solutions here! – jwueller Sep 17 '10 at 08:10
  • 2
    @elusive : Thats correct, better solutions always be used. I have just given alternative solution. Hope you don't mind it. – Nik Sep 17 '10 at 08:43
  • 3
    Since not everyone necessarily knows the evilness of `eval()`, you should provide this information in your post. Nobody should use this solution unless he has a very good reason and is exactly knowing what he is doing. `eval()` has its valid uses but this is not one of them. – jwueller Sep 17 '10 at 13:12
  • 2
    @elusive: Thanks for advice. I have added disclaimer now. Please check. – Nik Sep 17 '10 at 13:28
  • Never. Ever. EVER use eval. Ever. There's no valid use cases for it. If you think you need it, you need to re-evaluate what you're doing. – Hybrid web dev Jul 09 '21 at 05:14
  • I see lots of widgets are using eval. We just don't have to promote using eval at the first place. – kta Jul 12 '23 at 08:55
2

An example to pass an array of params to those composed functions, .

/* Store function names and match params */
let at = {
    at_26 : (a,b,c) => at_26(a,b,c),
    at_21 : (a,b,c) => at_21(a,b,c),
    at_99 : (a,b,c) => at_99(a,b,c),
    at_om : (a,b,c,d,e) => at_om(a,b,c,d,e)
}

/* Dynamic function router: name + array of Params */
function dynFunc(name, arrayParams){
  return at[name](...arrayParams)
}

/* Usage examples */ 
dynFunc(`at_${99}`, ["track001", 32, true])
dynFunc("at_" + "om", ["track007", [50, false], 7.123, false, "Bye"])


/* In the scope */
function at_99(a,b,c){
  console.log("Hi! " + a,b,c)
  console.log(typeof(a), typeof(b), typeof(c))
}
function at_om(a,b,c,d,e){
  console.log("Hi! " + a,b,c,d,e)
  console.log(typeof(a), typeof(b), typeof(c), typeof(d), typeof(e))
}
NVRM
  • 11,480
  • 1
  • 88
  • 87
1

There is a better way then the window object - which is NOT friendly in firefox - use "self" instead - so in the example posted by Quentin it looks like this:

self['at_' + test_id]();

bigdave
  • 19
  • 2