NGauthier
NGauthier

Reputation: 901

How to call a function from a string?

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

Answers (2)

David Hellsing
David Hellsing

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

NGauthier
NGauthier

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

Related Questions