Q:

how to avoid nested switch?

I'm creating a contextual menu in JavaScript for a web app. The menu can appear in numerous contexts, and have different choices. I could have a different function for each context/choice:
grid1_delete()
grid1_duplicate()
grid2_delete()
grid2_add()
grid2_duplicate()

and hard code those in as the menu is being built. The thing I don't like about that is there will probably be a lot of repeated code. So I was thinking about using a dispatcher function, but it's resulting in potentially long, nested switch statement thus:
function contextMenuClick(context, menuItem) {
    var action = menuItem.innerHTML;
    switch (context) {
        case 'grid1':
            switch(action) {
                 case('delete'):
                      // do delete for grid1
                      break;
                 case('duplicate'):
                      // do duplicate for grid1
                      break;
                 default:
                      console.log('undefined action in contextMenuClick/grid1: ' + context);
            }
            break;
        case 'grid2':
            switch(action) {
                 case('add'):
                      // do add for grid2
                      break;
                 case('delete'):
                      // do delete for grid2
                      break;
                 case('duplicate'):
                      // do duplicate for grid2
                      break;
                 default:
                      console.log('undefined action in contextMenuClick/grid2: ' + context);
            }
            break;
        default:
            console.log('undefined context in contextMenuClick: ' + context);
        }

Yuck. There's got to be a better way. Maybe the dispatcher is more trouble than it's worth. I've looked at some of the related posts, but I'm not quite getting how to apply them to this exact situation.

A:

Switch statements are very rarely necessary in Javascript.  In general, you can just use objects like dictionaries/maps and do the lookup directly: foo.bar is equivalent to foo['bar'].
Also, for "global" variables, some_global_func() is equivalent to window.some_global_func(), which can also be written as var f = 'some_global_func'; window[f](): you don't ever need eval in order to select a variable or call a function dynamically based on its name.  In general, when doing that, though, you should prefer to store the function in an object rather than at global scope (i.e. in the window object).
So, assuming that grid1_delete and grid2_delete are fundamentally different and can't be combined into a generic function, you could do something like the following without changing your code much:
var grid_actions = {
    'grid1': {
        'delete': function() { /* ... */ },
        'duplicate': function() { /* ... */ }
    },
    'grid2': {
        'delete': function() { /* ... */ },
        'add': function() { /* ... */ },
        'duplicate': function() { /* ... */ }
    }
}

function contextMenuClick(context, menuItem) {
    var action = menuItem.innerHtml;
    if (context in grid_actions) {
        if (action in grid_actions[context]) {
            grid_actions[context][action]();
        } else {
            console.log('undefined action in contextMenuClick/' + context + ': ' + action);
        }
    } else {
        console.log('undefined context in contextMenuClick: ' + context);
    }
}

A better solution, though, is to refactor things to have have these functions be methods of objects for each context, like @le dorfier suggests.

