Javascript 使用jQuery执行动态传递的函数调用

Javascript 使用jQuery执行动态传递的函数调用,javascript,jquery,Javascript,Jquery,我已将此函数调用作为字符串传递: var dcall = "tumbsNav(1)"; 是否可以像SQL中的exec那样动态执行此命令 exec(dcall) eval是等效的,但您不应该使用它 相反,按如下方式传递函数: var dcall = function() {tumbsNav(1);}; 然后用以下词语来称呼它: dcall(); 为此,您需要eval(dcall) eval可以在程序中打开。如果你需要使用它,那通常意味着你的程序设计得很糟糕 相反,您可以保留对要调用的函数的

我已将此函数调用作为字符串传递:

var dcall = "tumbsNav(1)";
是否可以像SQL中的exec那样动态执行此命令

exec(dcall)

eval
是等效的,但您不应该使用它

相反,按如下方式传递函数:

var dcall = function() {tumbsNav(1);};
然后用以下词语来称呼它:

dcall();

为此,您需要
eval(dcall)

eval
可以在程序中打开。如果你需要使用它,那通常意味着你的程序设计得很糟糕

相反,您可以保留对要调用的函数的引用,并保存一个参数数组并使用,例如,
tumbsNav.apply(null,[1])。我不知道您的代码,所以这是我能提供的最通用的解决方案。

使用eval(dcall)

正如其他人提到的,eval被认为是不好的做法。主要原因是

1) 不正确的使用会使代码容易受到注入攻击

2) 维护代码变得更加困难(没有行号,无法使用调试工具)

3) 执行速度较慢(浏览器无法编译)

4) 范围变得无法预测


然而,如果您了解所有这些,那么eval将非常有用。

无论您存储在哪里

var dcall = "tumbsNav(1)";
你可以改为去商店

var dcall = function() {
   return tumbsNav(1);
};
无论你在哪里打电话,而不是打电话

eval(dcall);
你可以打电话

dcall();
如果在调用
var func=…
时未定义
tumbsNav
,则这种情况唯一不起作用。然后,您必须存储字符串。如果字符串完全在您的控制之下,那么就没有安全漏洞,但是要注意@Porco提到的所有问题

正如Kolink所提到的,如果在使用调用tumbs的包装匿名函数为其赋值时未定义
tumbsNav
,则我的示例不会导致问题。上述评论只有在以下示例中才有意义:

var dcall = tumbsNav, darg = 1;
// later in the code, you can call
dcall(darg) ;

更简单地说(因为您知道参数的数量),您可以调用
tumbsNav(1)
True,但我希望它尽可能通用,以防OP需要在其他地方使用此模式。@RegisteredUser。为什么使用
eval
是一个更好的问题,事实上,如果我能<代码>:-)
eval启动编译器。通常有一种更有效的方法来解决大多数问题而不使用eval。查看这篇文章,了解为什么不使用eval以及应该使用eval的原因。我的回答提到了一个案例,您需要
eval
。如果将
tumbsNav
分配给
dcall时未定义它;这不是一个非常常见的场景,但仍然是一个有效的场景。我唯一不同意的一点是,范围并非无法预测。它在运行eval的范围内运行。它可能是不可预测的,如图所示:抱歉,Porco,但该页面上的行为与我预期的一样。eval的范围在一个函数中,没有理由更改全局变量。在该函数中写入
eval(“var foo=456”)
与在该函数中写入
var foo=456
的效果完全相同。唯一不可靠的情况是,如果您调用
window.eval()
,或者如果您将第二个参数传递给
eval(“code”,scope)
(顺便说一句,它已被弃用)。总之,如果您以非标准的方式使用它,那么它是不可靠的。这里的链接表明window.eval也被弃用了。感谢这些链接,您已经改变了我的想法。我曾考虑过删除它,但我更喜欢这个引人注目的想法:)事实上,如果创建函数时未定义
tumbsNav
,您就错了。调用tumbsNav时,它接受tumbsNav
的任何值,而不是以前的值。这是许多闭包错误的主题。@Kolink oops,你说的是100%正确的,匿名函数内容在函数被调用之前不会被计算。我最初写这个答案时指定了
var dcall=tumbsNav,darg=1
并调用dcall(darg)
,在这种情况下,我的评论是准确的。