tags:

views:

478

answers:

5

In JavaScript, if I have a string in a variable, is there a way to get a reference to the function object which has that matching name? Note that jQuery is available to me so I can use any of its helper methods also.

For example:

myFunction = function(){};

var func_name = "myFunction";
var myFunctionPtr = ???  //how to get the function from the name

Thanks

+7  A: 

if you know that its a global function you can use:

var functPtr = window[func_name];
//functPtr()

Otherwise replace window with the parent object containing the function.

mkoryak
+3  A: 

this[func_name] should give you the function.

var myfunc = this[func_name];
myfunc();
Max Schmeling
I just tried that in Firebug and it didn't work. Maybe it behaves differently in a web page?
rmeador
It depends on where your function is defined. If the function is not defined on 'this' then it won't find it. You may need to try window[func_name] or Some.Other.Object[func_name]
Max Schmeling
A: 

Use eval:

myFunction = function(){};

var func_name = "myFunction";
var myFunctionPtr = eval(func_name);
Jon Benedicto
eval is evil. dont use eval
mkoryak
why? can you cite some good reasons.
Jon Benedicto
http://stackoverflow.com/questions/86513/why-is-using-javascript-eval-function-a-bad-idea
Miles
thanks for the link. as with all programming languages, libraries and methods, it can be abused. The key is using it correctly, and knowing what one is doing. If those conditions are met, it's the right tool for the job.
Jon Benedicto
The thing with eval is that when it seems like a viable solution, 99.9% of the time, it's an indicator that you're approaching the problem in the wrong way. In this case, it's unlikely that the OP really should be getting a function in the current scope by name; instead, the functions should probably be stored in an Object so that they can be directly looked up by key.
Miles
I get your point - but I wouldn't let that make eval "evil" :-) just in this instance, the OP should probably think up a better design.
Jon Benedicto
+4  A: 

I just did a quick test in Firebug and I was able to get the function from the name by simply eval()ing the name... I feel dirty using eval(), but it seems to get the job done here quite nicely.

var myFunctionPtr = eval(func_name);
rmeador
Can you pass parameters in that way?
Max Schmeling
Certainly -- once you have myFunctionPtr, you use it as a regular function.
Rick Copeland
or you can use window[func_name] which gets the job done too.
mkoryak
@mkoryak -- not if the function you're looking up is not globally defined
Rick Copeland
If the function you're looking up is not globally defined, you should put it into an object so that you can look it up by a key.
Miles
A: 

A safe way to do is to sandbox the alleged function while testing its type:

function isFunction(expr) {
    function sandboxTemplate() {
        var window, document, alert; // etc.

        try {
            return typeof $expr$ == "function";
        } catch (e) {
            return false;
        }
    }

    try {
        var sandbox = new Function(
            sandboxTemplate.toString().replace("$expr$", expr)
            + "return sandboxTemplate()");
        return sandbox();
    } catch (e) {
        return false;
    }
}

function test(expr) {
    document.write("<div>\"" + expr + "\" <b>is "
        + (isFunction(expr) ? "" : "not ")
        + "</b>a function</div>");
}

/* Let's do some testing */

function realFunction() {
}

test("realFunction");       // exists!
test("notHere");            // non-existent
test("alert('Malicious')"); // attempt to execute malicious code!
test("syntax error {");     // attempt to blow us up!

The output:

  • "realFunction" is a function
  • "notHere" is not a function
  • "alert('Malicious')" is not a function
  • "syntax error {" is not a function

The sandboxing code could be written in a more concise manner but I like using "template" functions instead of embedding JS code as string literals.

And oh, this does it nicely without using eval -- though one can argue that using a Function constructor is no different than an eval.

Ates Goral