views:

478

answers:

3

I've seen this technique for calling a Javascript function based on the value of a string variable.

function foo() {
    alert('foo');
}

var test = 'foo';

window[test]();  //This calls foo()

Is this the accepted way to do it or is there a better way? Any cross-browser issues to worry about?

A: 

You can use eval(str)

eval('foo();');
Gee
-1. There is no need to use eval here.
SolutionYogi
Did I understand the question wrong? why is eval wrong?
Gee
Using eval you invoke the Javascript parser and goodness knows what else that is need to take text and turn it into a set of instructions that can be executed. window['foo']() works so eval should be avoided in this case
AnthonyWJones
Generally speaking, you should avoid using eval as it starts JS interpreter to execute code specified to eval. Additionally, user wants to execute a function given he has a name of the function in a string variable. Your code doesn't really do that.
SolutionYogi
+4  A: 

Looks fine to me. I would probably create a simple helper function like following:

function runFunction(name, arguments)
{
    var fn = window[name];
    if(typeof fn !== 'function')
        return;

    fn.apply(window, arguments);
}

//If you have following function

function foo(msg)
{
    alert(msg);
}

//You can call it like

runFunction('foo', ['test']); //alerts test.
SolutionYogi
+1, beat me to it and had a better caller function.
tj111
Good answer. I think having a helper that does some sanity checking is a great idea.
Mark Biek
How often would you call a function declared at the global scope and give it a context other than null? (btw I think your use of the word scope is misleading, context would be better)
AnthonyWJones
I thought long and hard about it and you are right, there won't be a situation where I would need to pass scope to the global function, will modify the code.
SolutionYogi
+2  A: 

I personally wouldn't bother even with a helper function

  window[someKey]('test')

would be fine.

However I wouldn't general maintain a set of possible functions to call at the global scope anyway. Hence I would use a more general pattern:-

 obj[someKey]('test')

where obj may be this, a property of this or variable from a closure.

AnthonyWJones