Map of functions in javascript?
I have a context menu that will trigger different javascript functions. The naive solution for choosing function looks like this:
function(action, el, pos) {
switch(action)
{
case "export_selected_to_excel":
exportSelectedToExcel(el);
break;
etc..
}
}
I would like to have a map of functions instead, so that I can reduce the metod to something similar to this:
function(action, el, pos) {
menuAction[action](el);
}
I define the array like this:
function exportSelectedToExcel(id){
//stuff...
}
var menuAction = new Array();
menuAction["export_sel开发者_如何学Goected_to_excel"] = exportSelectedToExcel;
This seems to work fine and feels like a reasonable solution.
Are there any downsides to do like this in javascript?
Is there even better ways to do it?Your idea is good, but you should not use Arrays as associative maps, because they are not associative (see e.g. Mastering Javascript Arrays). When you do var a = []; a["x"] = y
you assign in fact the property x
to the object a. So, it holds true afterwards: a.length == 0 and a.x == y
.
You should just replace Array
by object to get an associative map:
var menuAction = {};
menuAction["export_selected_to_excel"] = exportSelectedToExcel;
// or
menuAction.export_selected_to_excel = exportSelectedToExcel;
// or
menuAction.export_selected_to_excel = function(id) {...};
or:
var menuAction = {
export_selected_to_excel: exportSelectedToExcel,
export_x: exportX // etc
}
if you do it like that the function will point to another function and thus create some overhead, you can also define the function directly inside of the object, so for example:
var menuAction = {};
menuAction.export_selected_to_excel = function (id) {
// stuff
}
and to make sure a function exists you can do:
var action = 'export_selected_to_excel';
if(typeof menuAction[action] == 'function')
{
// call function
}
if it is really the case that the names of the functions can be directly derived from the strings, eg,
export_selected_to_excel => exportSelectedToExcel
compute_selected => computeSelected
...
...then rather than using an associative array, you could dynamically generate the fn names and invoke them dynamically.
Use the answer to this question ( Convert hyphens to camel case (camelCase) ) to convert names.
Then, use the answer to this question ( How to execute a JavaScript function when I have its name as a string ) to invoke the function. Be sure to verify that window[functionName]
is an actual function, with a typeof
test.
I don't think there are big downsides. Indeed what you're trying to do is similar at what you do when you define an object and inside declare your functions.
e.g.:
var menuAction = {
function action1(el) {
// ...
},
function action2(el) {
//...
},
// ...
}
The only dfference is that in this case you're defining you're functions not in the object declaration but a-posteriori using the Associative Array notation.
精彩评论