动态调用方法

时间:2014-07-03 14:06:24

标签: javascript string firefox-addon eval

尝试动态调用特定方法时遇到问题。问题更大,但我会尽量解释。我有一个具有一些功能的管理器,我需要使用eval执行其中一个(不管怎样,我只需要使用它)。所以,我有:

function Manager(){};
Manager.prototype.loadApp = function(src){
    eval("this.loadBlueApp(" + src + ");");
}
Manager.prototype.loadBlueApp = function(src){
    alert("Great! " + src);
}

但是当我用" Blue"参数,我需要执行loadBlueApp()。

var man = new Manager();
man.loadApp("You can call me 'Looloo'");

但每次我尝试执行它时,都会给我发错: 在元素列表之后缺少]

我可以通过在参数区域中添加单引号来使其工作,但如果字符串包含任何单引号,则会抛出错误(并且必须不更改该字符串)。

eval("this.loadBlueApp('" + src + "');");

我真的无法改变String src包含的内容。有时字符串包含双引号或单引号,有时两者都包含。

所以,我真的不知道该怎么做。你能帮助我吗?非常感谢! 小提琴:http://jsfiddle.net/S49MX/6/

3 个答案:

答案 0 :(得分:2)

请勿使用eval! 既然你标记了这个,那就加倍了! addons.mozilla.org网站将拒绝不必要地使用eval的加载项。

你想要的只是:

Manager.prototype.loadApp = function(src){
    this.loadBlueApp(src);
};

您写道,函数名称可能在参数中,而不是静态的。然后使用

Manager.prototype.loadApp = function(functionName, src){
    this[functionName](src);
};

可以像manager.loadApp("loadBlueApp", "something");

一样调用它

甚至:

Manager.prototype.loadApp = function(functionName, src){
    this["load" + functionName](src);
};

可以像manager.loadApp("BlueApp", "something");

一样调用它

或者@Havenard只需恰当地设置loadApp

Manager.prototype.setApp = function(functionName) {
  this.loadApp = this[functionName];
};

Fiddle展示了以上所有内容。

PS:如果你因为某种原因真的有eval在Firefox附加组件中使用某些内容,请在约束Components.Sandbox / Components.evalInSandbox中执行此操作。

实际上a whole article on MDN(基于弗拉迪米尔的Five wrong reasons to use eval() in an extension文章)。

答案 1 :(得分:1)

我不会评论使用eval,因为你说“无关紧要为什么,我只需要使用它”。但在这里,让我们解释你当前的评估:

eval("this.loadBlueApp(" + src + ");");

将通过以下方式得到:

this.loadBlueApp(You can call me 'Looloo');

此处存在语法错误。您还需要添加引号以将字符串作为参数传递:

eval("this.loadBlueApp(\"" + src + "\");"); //Note the escaped quotation

这将导致对

的解释
this.loadBlueApp("You can call me 'Looloo'");

没有语法错误。

转义引号可能会很有趣,因此它可以防止关闭字符串错误:

eval("this.loadBlueApp(\"" + src.replace(/"/g, '\\"') + "\");");

小提琴:http://jsfiddle.net/nLuZB/

答案 2 :(得分:0)

您需要在最后eval声明中注明引号。我在你的jsfiddle上改变了双/单引号的顺序,它起作用了:

try{
    function Manager(){};
    Manager.prototype.loadApp = function(src){
        return eval("this.loadBlueApp('" + src + "');");
    }
    Manager.prototype.loadBlueApp = function(src){
        alert("Great! " + src);
    }

    var man = new Manager();
    man.loadApp('You can call me "Looloo"');

}catch(err) {
    alert(err.message); //missing ] after element list

当我查看时,您使用单引号'Looloo',这会在'" + src + "'

中终止您的字符串

另外,我知道其他人已经这样说了,我知道这不是你想听到的......但你可能不需要使用eval来做你正在做的事情。如果不深入研究您的实际问题,我可以告诉您还有其他一些选择。一种可能是将函数(或对象)存储在对象中并通过键进行引用。

myFuncs[key]();

myObjs[key].loadApp();