开发者

Alternative to the "switch" Statement

I开发者_如何学C 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?


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
  // ...
}


I used a structure like this today:

var chosenColor = 'red';

var colorString = {
    'red': 'The color is red.',
    'green': 'The color is green.',
    'blue': 'The color is blue.',
}[chosenColor] || 'The color is unknown.';

I like that it's a really small amount of code to choose a string based on choice.

You could also pass it to a function:

alert({
    'red': 'The color is red.',
    'green': 'The color is green.',
    'blue': 'The color is blue.',
}[chosenColor] || 'The color is unknown.');


You could use object literals, and try catch to trap the default:

function write(what) {
    var colors = {
    'Blue': function(){ alert('Light-Blue'); },
    'Red': function(){ alert('Deep-Red'); },
    'Green': function(){ alert('Deep-Green'); }
    }
    try {colors[what]();}
    catch(err) {colors['Green']();}//default behaviour
}
write('Pink');


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.


I had to do do a compare for a group sort of object props for a list and did not want to do a switch/case for all the possibilities so I did an array of objects assignment to a numeric rank first so the case became a simple compare. This is only 4 possibilities but you get the drift of how to extend this to situation where a switch/case becomes unmanageable:

function mySort2(item1,item2){

     var matrix = {  
    'repair': 4,  
    'r/r': 3,  
    'part': 2,  
    'misc': 1  
  };  

(matrix[item1.category] < matrix[item2.category]) ? return +1 : return -1;

// if possible bad data need to check for this first ???

i1=matrix[item1.category] || null;
i2=matrix[item2.category] || null;

if (i1==null){
    // handle bad data in item 1
    return +1; // put it after 2
}

if (i2==null){
    // ditto 
    return -1; //put 1 first
}

if (i1<i2) 
    return +1;
else 
    return -1;

}


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.


Alternatively, you can also use Dictionaries, so you could see the type of the function return, I think it's clean and scalable, although it's just pure JS.

const ColorDictionary = {
  red: 'applies red color',
  blue: ' applies blue color',
  green: 'applies green color',
}

const useShowColors = (color) => {

 // color will be selected or fallout to default value.
 const getColor = () => (
  ColorDicionary[color] ?? 'applies default color' 
 )
 
 return { getColor }
}

const { getColor } = useShowColors() //pass the color you wish.


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.


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]();
}
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜