9

What I want is to pass a function's name as a string and have that be as if I passed a reference to the function. For example, I want to make this:

var test = function(fn){
  fn();
}
test(alert);

Equal to this:

var test = function(function_as_string){
    //...code that converts function_as_string to function reference fn
    fn();
}
test('alert');

How can I do this?

6 Answers 6

5

You get the function reference from the window object:

var fn = window[function_as_string];

Demo: http://jsfiddle.net/Guffa/nA6gU/

Sign up to request clarification or add additional context in comments.

6 Comments

If the function was not a global function, let's say for example it was in the test function I could use test[function_as_string] just as well?
@Aust: If a function is declared inside another function, then it's local so it only exists while that function is running, so you can't get it at all from outside the function.
var fn = window[alert]; fn("yes"); result: TypeError: fn is not a function on FF 15
@GungFoo: Try window['alert'].
yeah.. that's the reference to the function, but how do i actually call it?
|
3

Functions are properties on an object. You can access them like any property and then use () to execute them.

​var o = {};
​​​​
o.b = function b() {
    alert("b");
}

o.b();

o["b"]();

If its a global function then its a property on window.

function a() {
    alert("a");
}

a();

window.a();

window["a"]();

In terms of your nested question, the best approach is to assign it as a property to an object that you will have access to later. For example:

function assignInside() {
    o.inside = function() {
        alert("inside");
    }
}

assignInside();
o["inside"]();

Here it all is as a jsfiddle.

PS, There is no reason to use eval in this case and lots of good reasons to avoid eval in general.

Comments

1

Use eval to get a reference to the function -

var Namespace = {
    quack: function () {console.log('quack!')}
};

function test (fnName) {
    var fn = eval(fnName);
    fn();
}
test('Namespace.quack')

This could potentially allow you to pass other arguments in if you wanted to.

Oh, and the reason that you may not be able to simply use window[fnName] is if it's something like $.ajax - window['$.ajax'] will give you undefined.. so unless you want to create a complex function for looking up whether or not it's in another namespace, eval is your best bet.

3 Comments

As I just commented to @GungFoo, I've heard that using eval is bad. Is it bad in this case?
eval is like dynamite - its potentially dangerous if used for the wrong thing. However, like dynamite, it certainly has its uses - this would be one of them.
it seems to also be slow.. :o
1

Take a look at the eval() function, it will let you supply a string that is evaluated as javascript:

https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/eval

var test = function(fn){
  eval(fn + "()");
}
test(alert);

Notes on eval from MDN:

eval() is a dangerous function, which executes the code it's passed with the privileges of the caller. If you run eval() with a string that could be affected by a malicious party, you may end up running malicious code on the user's machine with the permissions of your webpage / extension. More importantly, third party code can see the scope in which eval() was invoked, which can lead to possible attacks in ways of which the similar Function is not susceptible.

eval() is also generally slower than the alternatives, since it has to invoke the JS interpreter, while many other constructs are optimized by modern JS engines.

There are safe (and fast!) alternatives to eval() for common use-cases.

look here: https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/eval

2 Comments

I've heard eval is bad to use. Would it be bad in this case?
If you are not using user input and hand it to the eval function i don't see why. Besides.. an evil user can always use the browsers console to inject code anyways. javascript is client-side and client-side security doesn't exist. :)
1

What about:

var fn = new Function(function_as_string)

3 Comments

I'm not trying to make a new function. I'm trying to call a function that already exists.
Then why are you passing that as string? Functions are first class so you can just pass the function around as a callback for example
I have no choice but to pass it as a string unfortunately.
0

Convert the string to the function using Function Object

const value = '(x, y) => x + y;';
const result = Function('return ' + value)();
console.log(result(1, 3)) // 3

immediately calling the Function object will return the value as a function

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.