1

I have an array that has a bunch of function names. I am not storing the function in an object.

for (i = 0; i < view_functions.length; i++) {
    view_functions[i]();
}

This doesn't work, any ideas?

Thanks.

  • You can store the functions themselves? – Namaskar Oct 05 '17 at 20:39
  • https://stackoverflow.com/questions/359788/how-to-execute-a-javascript-function-when-i-have-its-name-as-a-string – Peter Oct 05 '17 at 20:39
  • If the array stores name strings, you cannot call those. Please post your complete code showing what `view_functions` is and where else the functions are defined. – Bergi Oct 05 '17 at 20:41
  • the array is just the name of the functions. Ex. header, body, footer... So I want header(); to load. – Ryan Christopher Oct 05 '17 at 20:50
  • My second example covers that. Magic strings and `eval` are all generally frowned upon though. If you are declaring the names in your code, the first example would be better. – Fenton Oct 05 '17 at 20:51

1 Answers1

0

The code you posted works, so perhaps the code that defines the functions isn't quite right. Here is a fully working example.

function yep() {
     alert('Yep');
}

function again() {
    alert('Again');
}

var view_functions = [
    yep,
    again
];

for (var i = 0; i < view_functions.length; i++) {
    view_functions[i]();
}

If you wanted to get a bit of design help in your code, you could introduce a factory. This has the added benefit of making unknown function names explicit.

function yep() {
     alert('Yep');
}

function again() {
    alert('Again');
}

function functionFactory(name) {
    switch (name) {
        case 'yep':
            return yep;
        case 'again':
            return again;
        default:
            throw `${name} not a known function in functionFactory`;
    }
}

var view_functions = [
    'yep',
    'again'
];


for (var i = 0; i < view_functions.length; i++) {
    var func = functionFactory(view_functions[i]);
    func();
}

If you only have string names, I recommend not using string names... but you could go full-evil and use eval...

function yep() {
     alert('Yep');
}

function again() {
    alert('Again');
}

var view_functions = [
    'yep',
    'again'
];

for (var i = 0; i < view_functions.length; i++) {
    var n = view_functions[i] + '()';
    eval(n);
}

But why not store the actual functions in the array instead...

Fenton
  • 241,084
  • 71
  • 387
  • 401
  • No idea why someone downvoted this. It does in fact work. – agm1984 Oct 05 '17 at 20:41
  • some people just like to down vote it seems this works fine – schylake Oct 05 '17 at 20:42
  • "I have an array that has a bunch of function names. I am not storing the function in an object." This doesn't actually answer the question asked. – user94559 Oct 05 '17 at 20:43
  • What smarx said. lol... – Ryan Christopher Oct 05 '17 at 20:49
  • Man, do not do the eval.... read the duplicate link with solutions.... – epascarello Oct 05 '17 at 20:57
  • @epascarello - the eval is not the problem with that solution, it is a symptom of the problem. The first solution is there as the "better way". Replacing `eval` with `window[name]()` does not make magic strings better. – Fenton Oct 06 '17 at 07:37
  • but doing one of the solutions with the methods registered to an object is a lot better than eval. – epascarello Oct 06 '17 at 12:43
  • @epascarello that was my motivation for supplying multiple alternatives, and highlighting the weakness of the third solution. `eval` is not the problem in the last example - it isn't nice, but there is a much more fundamental design problem (that will be discovered when someone improves the name of one of those functions). – Fenton Oct 06 '17 at 13:18
  • My problem is that I can't store the function in an object because the function name is coming from the JSON which handles all the views. Because preloading views and having the functions launch inside the view doesnt actually preload the view... it's a weird predicament. – Ryan Christopher Oct 06 '17 at 15:56
  • Hi Ryan, the second option covers that scenario, and de-couples your code from wherever that JSON comes from. – Fenton Oct 06 '17 at 18:06