“switch”语句的替代方案

29

我不想在我的代码中使用Switch语句,因此我正在寻找一些替代方法。

使用Switch的示例:

function write(what) {

  switch(what) {

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

    ...

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

  }

}

没有使用Switch的示例:

colors = [];

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


function write(what) {

  colors[what]();

}

我的问题是:

  1. 你知道其他的替代方案吗?
  2. 这是最好的解决方案吗?

8
太好了,不要动它。 - codeholic
2
是的,这是更好的解决方案,代码更少 :) - Sarfraz
它也更加简洁、易读,可能还能消除重复的代码。 - brian
9个回答

25
我只有一个关于你第二种方法的笔记,你不应该使用数组来存储非数字索引(在其他语言中,你会称之为关联数组)。
你应该使用一个简单的对象。
此外,你可能想检查传递给你的write函数的what参数是否存在于你的colors对象的属性中,并检查它是否是一个函数,这样你就可以在没有运行时错误的情况下调用它。
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
  // ...
}

恕我直言,我认为你链接的文章是错的。相反,我们不应该使用for..in来迭代一个数组。 - machine elf
1
@machine: 那篇文章还谈到了for...in语句以及当扩展内置构造函数的原型成员(如ArrayObject)时会出现的问题,但文章的底线是JavaScript数组应该是数字的,它们经常被用来存储任意键/值对,这是不好的实践... - Christian C. Salvadó
底线是什么?在数组上使用可扩展属性并不改变这个事实。将你可以使用的最通用对象之一变成最不通用的对象并没有什么好处。我不确定你为什么会说“该文章还提到”...... 我的理解是,这篇文章的整个重点是“更好地”支持使用for..in与数组。 - machine elf

19

今天我使用了这样的一个结构:

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.';

我喜欢它仅需要很少的代码就能根据选择来选择一个字符串。

你也可以将其传递给一个函数:

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

1
short and simple, like it. +1 - schellmax
1
只要chosenColor存在于colorString中,这就很酷。例如,如果chosenColor是“orange”,则会出现类型错误。 - northamerican
1
事实上,您可以通过以下方式轻松添加默认选项:({'red': 'the color is red'})[chosenColor] || 'default' - superzamp
谢谢@superzamp,我已经编辑了我的代码以添加默认选项。 - Jonathan L.
在2021年使用??代替|| - Sebastian Simon

3
您可以使用对象字面量和try catch来捕获默认值:
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');

1

我必须对列表中的一组对象属性进行比较,但不想为所有可能性做一个switch/case,因此我首先将对象分配给数字等级的对象数组,这样case就变成了一个简单的比较。虽然这只有4种情况,但你可以扩展到switch/case无法管理的情况:

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;

// 如果可能的话,需要先检查坏数据吗?

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;

}


这是一个答案:用于此目的的使用 switch/case 的替代方法。您还可以使用 [] of [] 来返回实际的值矩阵。 - Icedvolvo

1

问题2:

通常情况下,如果您可以用字典查找替换自定义控制结构,那么您就非常好。这种方法易于阅读,高度优雅 - 坚持使用它。


0

或者,你也可以使用字典,这样你就可以看到函数返回的类型。我认为这样做干净而且可扩展,尽管它只是纯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.

0

你已经接近成功了。如果可能的话,你可以添加一个帮助函数来使设置更容易。例如:

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

编辑:
如果你想为每个选项做更复杂的操作,那么这种方法显然行不通。正如@roe在评论中提到的那样,这使用了全局颜色,这经常被人们所反对。


2
这仅适用于此特定示例,实际上它们很少有太多共同点。另外,颜色在这里是全局的,这很少是件好事。 - falstro

-1

就像我说的一样,这很棒。我唯一可以为您的解决方案添加的是,最好将您的颜色本地化。

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

-1

另一种选择是定义一个带有write方法的类,并在子类RedBlue中覆盖它以执行正确的操作。

是否比您提出的解决方案更好,取决于您的具体情况。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接