0

I know there are a few similar questions already on SO (1, 2, 3) but unfortunately my limited knowledge of JS doesn't allow me to extrapolate the scenarios to my personal use case, hence this question.

I have the following piece of code which allows me to dynamically attach to and call from an object some functions, which works fine (available on JsFiddle):

JavaScript:

$.extend(true, window, {
    "MyPlugin": {
        "dynamicFunction": dummy_function
     }                
});

function dummy_function() {

}

function real_function(string) {
    alert(string);
}

function dynamic_call(function_name, text) {
    MyPlugin["dynamicFunction"] = eval(function_name);
    MyPlugin["dynamicFunction"](text);
}​

HTML:

<button onClick="dynamic_call('real_function','some text');">click me</button>​

UPDATE:

Funny enough, I was trying to replicate an issue I have whereby my function is scoped locally, but I ended writing an example where it isn't :) (I told you JS isn't my thing). Therefore all window[function_name] answers are correct, although I accepted James Allardice's because he extrapolated to the issue I was trying to resolve but didn't raise.

How can I achieve the same functionality without the use of eval?

Community
  • 1
  • 1
Max
  • 12,794
  • 30
  • 90
  • 142

5 Answers5

3

Function declarations in the global scope become properties of window, so you can use square bracket syntax:

function dynamic_call(function_name, text) {
    MyPlugin["dynamicFunction"] = window[function_name];
    MyPlugin["dynamicFunction"](text);
}​

If your function is not in the global scope, you could make it the value of a property of some object:

var myFuncs = {
    real_function: function () {
        alert(string);
    }
};

Then you can simply use:

MyPlugin["dynamicFunction"] = myFuncs[function_name];
James Allardice
  • 164,175
  • 21
  • 332
  • 312
2

You cannot do this without eval if the function is scoped locally. You can only do it without eval if the function is property of some object. This includes global object, so global functions can be done without eval.

With a global function or function that is property of some object:

MyPlugin["dynamicFunction"] = window[function_name];//window references global object
Esailija
  • 138,174
  • 23
  • 272
  • 326
1

If real_function is a gloabl function, you just call

window[function_name](text);
MaxArt
  • 22,200
  • 10
  • 82
  • 81
1

I know this is not the exact question, but if you can just pass in the function as a parameter, like this:

<button onClick="dynamic_call(real_function,'some text');">click me</button>​

function dynamic_call(f, text) {
   MyPlugin["dynamicFunction"] = f;
   MyPlugin["dynamicFunction"](text);
}​
Hogan
  • 69,564
  • 10
  • 76
  • 117
  • this is the best solution. there's no reason to pass a string when you can just pass the function. – jbabey Jul 13 '12 at 13:20
  • Couldn't cover everything with my example: I cannot pass the function name as a parameter, I get the function name from some HTML attribute value. Thanks but doesn't apply to my use case. – Max Jul 13 '12 at 13:24
1

Instead of using eval, reference function_name from the window object:

MyPlugin["dynamicFunction"] = window[function_name];
David G
  • 94,763
  • 41
  • 167
  • 253