Reputation: 901
How would you call a function from a string, possibly including a scope, and without using eval
.
The idea is that I want to specify a callback inside an a dragEndCallback
attribute, and call it giving the drag start and end objects as parameters. Some kind of generic drag and drop in my case.
Most people will tell you to use eval, but it's unsafe, slow, and a really bad idea overall.
Here are some sample strings that I would like to support:
"NamespaceA.functionName"
"functionName"
"NamespaceB.NamespaceA.functionName"
"ClassB.methodName"
Upvotes: 0
Views: 180
Reputation: 108510
If by "scope" you mean what scope to bring into the function, something like this could work:
var callFn = function(str, scope) {
scope = scope || window;
var namespaces = str.split('.'),
fn = window; // or whatever root you want
while(fn = fn[namespaces.shift()]){
if(typeof fn == 'function') {
fn.call(scope);
return;
}
}
};
Example:
window.ns = {
one: {
two: function(){ console.log('Two!') }
}
};
window.foo = function() {
console.log(this); // document
};
callFn('ns.one.two');
callFn('foo', document);
Upvotes: 0
Reputation: 901
Here is a generic, clean, and convenient way to do it. It returns undefined if the function was not found.
window.getFunctionFromString = function(string)
{
var scope = window;
var scopeSplit = string.split('.');
for (i = 0; i < scopeSplit.length - 1; i++)
{
scope = scope[scopeSplit[i]];
if (scope == undefined) return;
}
return scope[scopeSplit[scopeSplit.length - 1]];
}
Upvotes: 1