Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Map of functions in javascript?

Tags:

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_selected_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?

like image 564
Carl R Avatar asked Sep 12 '11 09:09

Carl R


3 Answers

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
}
like image 57
Jiri Kriz Avatar answered Sep 20 '22 14:09

Jiri Kriz


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
}
like image 20
jeffreydev Avatar answered Sep 21 '22 14:09

jeffreydev


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.

like image 35
Cheeso Avatar answered Sep 20 '22 14:09

Cheeso