如何在不使用eval的情况下从字符串创建方法调用

时间:2013-12-16 08:47:45

标签: javascript backbone.js

有人可以建议我如何使用字符串创建方法调用而不使用eval吗?请注意,methodCall无法进行硬编码,必须是动态的。 methodCall将动态创建。

在以下示例中,this引用了Backbone视图,例如

var amount = this.model.get('amount');

var $amount = this.$el.find('.amount');

var methodCall = 'this.parentController.parentController.addBinding';

//then need to call the method with args

methodCall('amount',$amount);

我首先想到这会起作用:

this['controller']['parentController']['view']['addBinding'](amount, $amount);

但是我开始意识到这也不会动态。有没有人有解决方案?

1 个答案:

答案 0 :(得分:2)

如本回答Multiple level attribute retrieval using array notation from a JSON object所述,您可以使用以下内容遍历对象的层次结构:

function findprop(obj, path) {
    var args = path.split('.'), i, l;

    for (i=0, l=args.length; i<l; i++) {
        if (!obj.hasOwnProperty(args[i]))
            return;
        obj = obj[args[i]];
    }

    return obj;
}

然后,您可以为视图/模型/集合提供应用任意路径的方法:

var V = Backbone.View.extend({
    dyncall: function(path) {
        var f = findprop(this, path);
        if (_.isFunction(f))
            return f.call(this, 'your args');
    }
});

var v = new V();
v.dyncall('parentController.parentController.addBinding');

演示http://jsfiddle.net/nikoshr/RweEC/

传递参数的灵活性更高:

var V = Backbone.View.extend({
    dyncall: function() {       
        var f = findprop(this, arguments[0]);
        if (_.isFunction(f))
            f.apply(this, _.rest(arguments, 1));
    }
});

var v = new V();
v.dyncall('parentController.parentController.addBinding', 'your arguments', 'another arg');

http://jsfiddle.net/nikoshr/RweEC/1/