How to execute a JavaScript function when I have its name as a string
Don't use eval
unless you absolutely, positively have no other choice.
As has been mentioned, using something like this would be the best way to do it:
window["functionName"](arguments);
That, however, will not work with a namespace'd function:
window["My.Namespace.functionName"](arguments); // fail
This is how you would do that:
window["My"]["Namespace"]["functionName"](arguments); // succeeds
In order to make that easier and provide some flexibility, here is a convenience function:
function executeFunctionByName(functionName, context /*, args */) {
var args = Array.prototype.slice.call(arguments, 2);
var namespaces = functionName.split(".");
var func = namespaces.pop();
for(var i = 0; i < namespaces.length; i++) {
context = context[namespaces[i]];
}
return context[func].apply(context, args);
}
You would call it like so:
executeFunctionByName("My.Namespace.functionName", window, arguments);
Note, you can pass in whatever context you want, so this would do the same as above:
executeFunctionByName("Namespace.functionName", My, arguments);
How to turn a String into a JavaScript function call?
Seeing as I hate eval, and I am not alone:
var fn = window[settings.functionName];
if(typeof fn === 'function') {
fn(t.parentNode.id);
}
Edit: In reply to @Mahan's comment:
In this particular case, settings.functionName
would be "clickedOnItem"
. This would, at runtime translate var fn = window[settings.functionName];
into var fn = window["clickedOnItem"]
, which would obtain a reference to function clickedOnItem (nodeId) {}
. Once we have a reference to a function inside a variable, we can call this function by "calling the variable", i.e. fn(t.parentNode.id)
, which equals clickedOnItem(t.parentNode.id)
, which was what the OP wanted.
More full example:
/* Somewhere: */
window.settings = {
/* [..] Other settings */
functionName: 'clickedOnItem'
/* , [..] More settings */
};
/* Later */
function clickedOnItem (nodeId) {
/* Some cool event handling code here */
}
/* Even later */
var fn = window[settings.functionName];
/* note that settings.functionName could also be written
as window.settings.functionName. In this case, we use the fact that window
is the implied scope of global variables. */
if(typeof fn === 'function') {
fn(t.parentNode.id);
}
Call a JavaScript function name using a string?
Property accessors can be used to access any object's properties or functions.
If the function is in the global scope, you can get it using the window object:
var myFunc = window[myFuncName];
This also works within the this
scope:
var myFunc = this[myFuncName];
How to execute a JavaScript Function When I have its name as a string (with parameters that have an overload argument)
Okay I figured it out instead of working with that crazy function, its actually much more simple than that.
const intent2 = {
where:
{ intent: intentBase }
}
const object = "intentS" + scamId + "A" + actorId + "Repository";
return await this[object]["findOne"](intent2)
This little code snippet can take in OVERLOADED PARAMETERS as an argument, which is terrific. It allows you to pass in custom built functions, so you don't have to have 20 different functions that perform basically exactly the same task. The return evaluates to exactly this:
return this.intentS*A*Repository.findOne(intent2);
Hopefully you won't have to go through what I did trying to figure this out. Good luck.
How to execute a JavaScript function having its name as a string in Edge
If you define your function straight to the window object then you can call it just with the string.
window.test=(args)=>{console.log("hello! " + arg)}
window["test"]("My first stack overflow answer")
will return "hello! My first stack overflow answer"
Execute a JavaScript function when I have its name as a string - Not working
Your code works as written. As multiple people have mentioned in comments, the reason your JSFiddle does not work is that you you have made the assumption that window
is the global scope in which you are operating. However, you have set your JSFiddle JavaScript to run onLoad
. This wraps it in a onload
handler. Thus, contrary to your assumption, your code is not running with window
as the global scope, which makes it not work. You can get your code working on JSFiddle by changing the JavaScript LOAD TYPE
option to either No wrap - in <head>
or No wrap - in <body>
.
Here is a JSFiddle that has that change implemented.
Also, below is your code in a snippet, which is working fine.
// a.callThis is the function that will be called using var string
var a = {
callThis:
function (ok, param1, param2) {
alert(ok + "|" + param1 + "|" + param2);
}
}
// Below is from
// http://stackoverflow.com/questions/359788
// /how-to-execute-a-javascript-function-when-i-have-its-name-as-a-string
function executeFunctionByName(functionName, context /*, args */) {
var args = [].slice.call(arguments).splice(2);
var namespaces = functionName.split(".");
var func = namespaces.pop();
for(var i = 0; i < namespaces.length; i++) {
context = context[namespaces[i]];
}
return context[func].apply(context, args);
}
// try call a.callThis by var string
var fn = 'a.callThis';
executeFunctionByName(fn, window, true, 'param1', 'param2');
Call a function starting only with the function name as a string (ES6 syntax)
It'd only be possible with eval
, which shouldn't be used:
eval(myFuncName + '()');
Instead, change your code so that the function is put onto an object (even if it's not the window), then use ordinary bracket notation to look up the property value (just like you're doing with window
, except with fns
instead), and call the retrieved function:
const fns = {
myFunc() {
console.log('do something');
}
};
const myFuncName = 'myFunc';
fns[myFuncName]();
How to execute a private JavaScript function when I have its name as a string
My ideal method for calling but does not work
foo[functionName]();
Yes, that's trying to access a [public] property on the foo
function. It would work with the "call"
method, for example.
This works but I'm trying to avoid eval. I'm not sure if this is not so bad
var func = eval(functionName);
func();
This works. I'm not sure if this is worse than funcRunner2 or the same;
eval(functionName + "()");
Both are as bad as the other from eval
s perspective. Option 1 just does make it easier to work with arguments [which need not be dynamically evaluated].
This works but requires the exec object which I would like to avoid if at all possible.
exec[functionName]();
That's just the way to do it. Since exec
is a local variable in the foo
scope, you even have your privateness. It seems you have switched exec
for publicObj
as well
// I would like to avoid doing this if I don't have to
var publicObj = {};
publicObj.test = function() {
bar();
}
The publicObj
variable is, despite its name, not public - it's declared local with the var
keyword! Btw, you could've simplified this to
var exec = {
test: bar
};
Related Topics
How to Make an Ajax Call Without Jquery
Weird Behavior With Objects & Console.Log
How to Sort an Array of Objects by Multiple Fields
Window.Close and Self.Close Do Not Close the Window in Chrome
Getting the Client'S Time Zone (And Offset) in JavaScript
"Uncaught Syntaxerror: Cannot Use Import Statement Outside a Module" When Importing Ecmascript 6
Map Function For Objects (Instead of Arrays)
How to Get the Difference Between Two Arrays in JavaScript
When Is .Then(Success, Fail) Considered an Antipattern For Promises
Why Can't I Directly Modify a Component'S State, Really
JavaScript Set Object Key by Variable
Formatting a Number With Exactly Two Decimals in JavaScript
Convert String to Title Case With JavaScript