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?
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?
Share Improve this question edited Sep 16, 2012 at 0:41 studgeek 14.9k6 gold badges90 silver badges97 bronze badges asked Sep 15, 2012 at 23:51 AustAust 11.6k13 gold badges46 silver badges75 bronze badges6 Answers
Reset to default 5You get the function reference from the window object:
var fn = window[function_as_string];
Demo: http://jsfiddle.net/Guffa/nA6gU/
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.
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.
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
What about:
var fn = new Function(function_as_string)
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