我有一个上下文菜单,会触发不同的javascript函数。 选择函数的天真解决方案如下所示:
function(action, el, pos) {
switch(action)
{
case "export_selected_to_excel":
exportSelectedToExcel(el);
break;
etc..
}
}
我希望有一个功能映射,以便我可以将metod减少到与此类似的东西:
function(action, el, pos) {
menuAction[action](el);
}
我像这样定义数组:
function exportSelectedToExcel(id){
//stuff...
}
var menuAction = new Array();
menuAction["export_selected_to_excel"] = exportSelectedToExcel;
这似乎工作正常,感觉像是一个合理的解决方案。
在javascript中有这样的缺点吗?
还有更好的方法吗?
答案 0 :(得分:4)
你的想法很好,但你不应该使用Arrays作为关联映射,因为它们不是关联的(参见例如Mastering Javascript Arrays)。当您执行var a = []; a["x"] = y
时,您实际上将属性x
分配给对象。所以,之后它仍然成立:a.length == 0 and a.x == y
。
您应该只按对象替换Array
以获取关联地图:
var menuAction = {};
menuAction["export_selected_to_excel"] = exportSelectedToExcel;
// or
menuAction.export_selected_to_excel = exportSelectedToExcel;
// or
menuAction.export_selected_to_excel = function(id) {...};
或:
var menuAction = {
export_selected_to_excel: exportSelectedToExcel,
export_x: exportX // etc
}
答案 1 :(得分:2)
如果你这样做,函数将指向另一个函数,从而产生一些开销,你也可以直接在对象内部定义函数,例如:
var menuAction = {};
menuAction.export_selected_to_excel = function (id) {
// stuff
}
并确保功能存在,您可以这样做:
var action = 'export_selected_to_excel';
if(typeof menuAction[action] == 'function')
{
// call function
}
答案 2 :(得分:1)
如果真的是函数的名称可以直接从字符串派生,例如
export_selected_to_excel => exportSelectedToExcel
compute_selected => computeSelected
...
...然后,您可以动态生成fn名称并动态调用它们,而不是使用关联数组。
使用此问题的答案(Convert hyphens to camel case (camelCase))转换名称。
然后,使用此问题的答案(How to execute a JavaScript function when I have its name as a string)来调用该函数。请务必通过window[functionName]
测试验证typeof
是否为实际函数。
答案 3 :(得分:0)
我认为没有大的缺点。 实际上,当你定义一个对象并在里面声明你的函数时,你所要做的就像你所做的那样。
e.g:
var menuAction = {
function action1(el) {
// ...
},
function action2(el) {
//...
},
// ...
}
唯一的不同之处在于,在这种情况下,您使用关联数组表示法定义了不是在对象声明中的函数,而是使用关联数组符号来定义函数。