views:

296

answers:

5

Hi all,

I do not want to use Switch in my code, so I'm looking for some alternative

Example with Switch:

function write(what) {

  switch(what) {

    case 'Blue':
      alert ('Blue');
    break;

    ...

    case 'Red':
      alert ('Red');
    break;

  }

}

Example without Switch:

colors = [];

colors['Blue'] = function() { alert('Blue'); };
colors['Red'] = function() { alert('Red'); };


function write(what) {

  colors[what]();

}

My questions are:

  1. Do you know any other alternatives?
  2. Is this best solution?
A: 

An alternative is to define a class with a write method, and override that in subclasses Red and Blue to do the right thing.

Whether or not that is better than your proposed solution, depends on your particular situation.

Thomas
A: 

You are pretty much there already. If possible you might want to add a helper function to make the setup easier. For Example:

function setup(what)
{
    colors[what] = function() { alert(what); };
}

EDIT:
If what you want to do for each option is more complicated clearly this will not work. As mentioned in the comments by @roe this uses the global colors which is often frowned upon.

smaclell
Great idea! Thank you.
Bambert
This only works for this particular example, chances are they don't have that much in common in reality. Also colors is a global here, which is rarely a Good Thing.
roe
I will edit the response to make that more apparent.
smaclell
+1  A: 

Question 2:

Generally, if you can replace custom control structures with a dictionary lookup, you're perfectly fine. It's easy to read and highly elegant -- stick with it.

Alexander Gessler
A: 

As I said, it's great. The only thing I can add to your solution is that it's perhaps better to localize your colors.

function write(what) {
    var colors = [];
    colors['Blue'] = function() { alert('Blue'); };
    colors['Red'] = function() { alert('Red'); };
    colors[what]();
}
codeholic
+6  A: 

I have only a note about your second approach, you shouldn't use an Array to store non-numeric indexes (that you would call in other languages an associative array).

You should use a simple Object.

Also, you might want to check if the what argument passed to your write function exists as a property of your colors object and see if it's a function, so you can invoke it without having run-time errors:

var colors = {};

colors['Blue'] = function() { alert('Blue'); };
colors['Red'] = function() { alert('Red'); };


function write(what) {
  if (typeof colors[what] == 'function') {
    colors[what]();
    return;
  }
  // not a function, default case
  // ...
}
CMS
With respect, I think the article you linked got it wrong. Rather, one shouldn't use for..in to iterate an array.
machine elf
@machine: That article also speaks about the `for...in` statement and the problems that come when the prototype member of built-in constructors like `Array` and `Object` is extended, but the bottom line of the article is that *JavaScript arrays are meant to be numeric*, and they are often used to store arbitrary key/value pairs which is bad practice...
CMS
Bottom line? Using expando properties on an array doesn't change that fact. There's nothing to gain by turning one of most versatile objects at your disposal into the least versatile. I'm not sure why you say "The article also speaks"... My understanding is that the entire point of the article is to 'better' support use of for..in with Arrays.
machine elf