views:

72

answers:

3

For simplicity's sake, I've included a script that dynamically calls a function by its name:

var foo = "hello";
var bar = "world";
var function_name = "say_" + foo + bar;

// Since its name is being dynamically generated, always ensure your function actually exists
if (typeof(window[function_name]) === "function")
{
    window[function_name](" World!");
}
else
{
    throw("Error.  Function " + function_name + " does not exist.");
}

function say_helloworld(the_word)
{
    alert("Hello " + the_word);
}

But the function say_helloworld's code is written in a static fashion. I would like something like:

var function_implementation = 'function say_'+foo+bar+
    '(the_world){alert("Hello " + the_world);}';
eval(function_implementation);

but without using eval(). There's an even uglier approach: doing an AJAX call to get the function.

Can you see a better approach?

+5  A: 

You can use an inline function expression:

window['say_'+foo+bar]= function(the_world) {
    alert('Hello '+the_world);
};

However, there is almost never a good reason to use dynamically-named variables. Store functions in a separate lookup object instead:

var says= {
    helloworld: function(the_world) {
        alert('Hello '+the_world);
    },
    somethingelse: function(otherthing) {
        alert('Something else with '+otherthing);
    }
};
says[somevar]('potatoes');
bobince
excellent answer, thank you!
altvali
+1  A: 

If you want to generate your function dynamically without eval you could use the constructor

Function([arg1[, arg2[, ... argN]],] functionBody)

This way you can do stuff like

var func = new Function('message', 'alert("Hello, " + message);')
func('world!');

See MDC for more instructions.

Cheers

Note: I have never used this approach before and I did not ever use the Function() constructor before. So I don't know if this might have any other drawbacks.

moxn
interesting, does it work with other rendering engines too?
altvali
@altvali It is included in the ECMA-262 3rd edition (http://www.ecma-international.org/publications/standards/ecma-262.htm) which is the base for Javascript 1.5. According to Wikipedia (http://en.wikipedia.org/wiki/JavaScript#Versions) even IE5.5 should understand that.
moxn
+1  A: 

You can use a timeout that will interpret you code, but it might be using the eval internally so not sure if you want this..

fText = 'function test(a){alert(a);}';
setTimeout(fText,0);

but you need to allow a few milliseconds before invoking it..

Gaby