如何将String转换为javascript函数调用(带对象的情况)

时间:2012-02-02 03:12:34

标签: javascript

是的,有许多问题,例如How to turn a String into a javascript function call?How to execute a JavaScript function when I have its name as a string

但是如果我们没有普通的函数名,但实际上是一个函数的对象属性名呢?

像:

var callMe = 'foo.bar.baz';

,预期调用的代码是:

window.foo = {
    bar: {
        baz: function() {
            alert('Eureka!');
        }
    }
};

为什么我需要这个:callback参数通过url传递,它可以(通过应用程序设计)是函数名或对象属性的FQN。

eval()之外的任何其他想法?

UPD

我的最终实施:

var parts = callbackName.split('.'),
    callback;

for (i in parts) {
    if (!callback) {
        callback = window[parts[i]];
    } else {
        callback = callback[parts[i]];
    }

    if (typeof callback === 'undefined') break;
}

if (typeof callback === 'function') {
    callback();
} else {
    console.error('Passed callback is not a valid function');
}

4 个答案:

答案 0 :(得分:5)

尝试

window['foo']['bar']['baz']()

如果这对你有用,应该很容易将'foo.bar.baz'翻译成。{/ p>

答案 1 :(得分:1)

请参阅下面的代码并查看小提琴(http://jsfiddle.net/bxsHp/):

window.foo = {
    bar: {
        baz: function() {
            alert('Eureka!');
        }
    }
};
//foo.bar.baz();
var callme = "foo.bar.baz";
var fn = window[callme.split(".")[0]];//get the first prop. bar
var len = callme.split(".").length;//length of obj tree
for(i=1;i < len;i++)
{//search for the next obj  
  fn = fn[callme.split(".")[i]];
}
if(typeof(fn) == "function")
{//check and call
  fn();
}

答案 2 :(得分:1)

您可以随时使用reduce()

callMe.split('.').reduce(function(prev, value) {
    return prev[value] || function() {};
}, window)();

jsFiddle

如果对象/函数列表在某处|| function() {},则undefined用于防止错误。如果您使用的是jQuery,则可以将空函数文字与$.noop()交换。

当然,支持旧IE会意味着您需要shim Array.prototype.reduce()

答案 3 :(得分:0)

这可能不是最优雅的方式,但它应该有效:

var callMe = "foo.bar.baz".split('.');

var callMeParts = callMe.split('.');

var fnCallMe = null;
var obj = window;
for (var i = 0; i < callMeParts.length; i++) {
    var prop = callMeParts[i];
    if (typeof obj[prop] === 'undefined') break;

    if ((i + 1) === callMeParts.length && typeof obj[prop] === 'function') {
        fnCallMe = obj[prop];
        break;
    }
    obj = obj[prop];
}

if (fnCallMe !== null) {
    fnCallMe.call(obj); // Call the function using the function container as the "scope"
}