JavaScript - 函数名中可以使用变量吗?

57
我希望这个问题不太简单,但是我一点也不知道 :(
如何使用变量作为函数名来启动一个函数?
例如...
我的函数:
function at_26();
function at_21();
function at_99();

开始执行函数

var test_id = 21;   
at_'+test_id+'();   // doesn't work

我希望有人能够帮助我。

先行致谢! Peter


6
为什么你需要那个?你可以创建一个名为 at() 的函数,并将你的数字作为参数传递给它。 - jwueller
5个回答

99

将你的函数存储在一个对象中,而不是将它们放到顶层。

var at = {
    at_26: function() { },
    at_21: function() { },
    at_99: function() { }
};

然后你可以像访问其他对象一样访问它们:

at['at_' + test_id]();

你也可以直接从window对象中访问它们...

window['at_' + test_id]();

...并避免将它们存储在对象中,但这意味着必须在全局范围内操作,应该避免这样做。


6
我更好奇为什么有人会创建100个只有索引不同的函数... - colithium
6
测试。假设你有一个实用程序库,类似于转换路径。你可能有一个路径数组,用来测试每个方法的效果。这是一种简单的方式,可以将实用程序添加到库中,而不必为每个新方法重复编写运行测试的代码。 - jonschlinkert
1
在我的情况下,它们并不一样。这只是一个它们可能不同的示例。有些仅在处理被操作的数据时需要稍微处理,因此将它们分类并使用类别跳转到处理程序会更简单。有各种各样有趣的用途。 - TheSatinKnight
@jonschlinkert 如果是这种情况,他们应该创建一个函数数组(这些函数甚至可以是匿名的),而不是数百个函数。请参见Express.js路由/中间件定义,了解如何正确处理此问题。 - slebetman
在我的情况下,我可以使用这个来进行“加”,“乘”,“除”等操作…… - Ac Hybl

28

你很接近了。

var test_id = 21
this['at_'+test_id]()

不过,你可能想要的是:

at = []
at[21] = function(){ xxx for 21 xxx }
at[test_id]()

12
这个代码的意思是:this['is_awesome']; // 谢谢。我会将其翻译成中文并保持原意,让它更通俗易懂。 - Giraldi

2

你也可以尝试

function at_26(){};
function at_21(){};
function at_99(){};

var test_id = 21;   
eval('at_'+test_id+'()'); 

但是如果你有非常强烈的理由使用 eval,请使用这段代码。在 JavaScript 中使用 eval 不是一个好习惯,因为它有一些缺点,比如“不正确地使用它可能会使你的脚本受到注入攻击”的风险。


6
不要在这种情况下使用 eval()!这里有更好的解决方案! - jwueller
2
@elusive:没错,更好的解决方案总是应该被采用。我只是提供了另一种选择。希望你不介意。 - Nik
3
由于并非每个人都了解 eval() 的危险性,因此您应该在您的帖子中提供这些信息。除非有非常好的理由并且确切知道自己在做什么,否则不应使用此解决方案。eval() 有其合法用途,但这不是其中之一。 - jwueller
2
@elusive:谢谢建议。我现在已经添加了免责声明。请检查。 - Nik
永远不要使用eval。永远。它没有任何有效的用例。如果你认为你需要它,那么你需要重新评估你正在做什么。 - Hybrid web dev
我看到很多小部件都在使用eval。我们根本不需要在第一时间推广使用eval。 - kta

2
一个将参数数组传递给这些组合函数的示例,Original Answer翻译成"最初的回答"。

/* Store function names and match params */
let at = {
    at_26 : (a,b,c) => at_26(a,b,c),
    at_21 : (a,b,c) => at_21(a,b,c),
    at_99 : (a,b,c) => at_99(a,b,c),
    at_om : (a,b,c,d,e) => at_om(a,b,c,d,e)
}

/* Dynamic function router: name + array of Params */
function dynFunc(name, arrayParams){
  return at[name](...arrayParams)
}

/* Usage examples */ 
dynFunc(`at_${99}`, ["track001", 32, true])
dynFunc("at_" + "om", ["track007", [50, false], 7.123, false, "Bye"])


/* In the scope */
function at_99(a,b,c){
  console.log("Hi! " + a,b,c)
  console.log(typeof(a), typeof(b), typeof(c))
}
function at_om(a,b,c,d,e){
  console.log("Hi! " + a,b,c,d,e)
  console.log(typeof(a), typeof(b), typeof(c), typeof(d), typeof(e))
}


1

有一个比window对象更好的方式——在火狐浏览器中不友好——使用"self"代替。因此,在Quentin发布的示例中,它看起来像这样:

self['at_' + test_id]();


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接