Альтернатива "переключателю"
Я не хочу использовать Switch в своем коде, поэтому я ищу альтернативу
Пример с переключателем:
function write(what) {
switch(what) {
case 'Blue':
alert ('Blue');
break;
...
case 'Red':
alert ('Red');
break;
}
}
Пример без переключателя:
colors = [];
colors['Blue'] = function() { alert('Blue'); };
colors['Red'] = function() { alert('Red'); };
function write(what) {
colors[what]();
}
Мои вопросы:
- Знаете ли вы другие альтернативы?
- Это лучшее решение?
9 ответов
У меня есть только примечание о вашем втором подходе: вы не должны использовать массив для хранения нечисловых индексов (который вы бы назвали на других языках ассоциативным массивом).
Вы должны использовать простой объект.
Кроме того, вы можете проверить, если what
аргумент передан вашему write
функция существует как свойство вашего 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
// ...
}
Я использовал такую структуру сегодня:
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.');
Вы можете использовать объектные литералы и попробовать 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');
Вопрос 2:
Как правило, если вы можете заменить пользовательские структуры управления поиском по словарю, у вас все отлично. Это легко читать и очень элегантно - придерживаться этого.
Я должен был сделать сравнение для группового вида объектов реквизита для списка и не хотел делать переключатель / регистр для всех возможностей, поэтому я сначала сделал массив присвоения объектов числовому рангу, чтобы случай стал простым сравнить. Это всего лишь 4 варианта, но вы понимаете, как распространить это на ситуацию, когда переключатель / случай становится неуправляемым:
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;
}
В качестве альтернативы вы также можете использовать словари, чтобы вы могли видеть тип возвращаемой функции, я думаю, что он чистый и масштабируемый, хотя это просто чистый 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.
Вы уже в значительной степени там. Если возможно, вы можете добавить вспомогательную функцию, чтобы упростить настройку. Например:
function setup(what)
{
colors[what] = function() { alert(what); };
}
РЕДАКТИРОВАТЬ:
Если то, что вы хотите сделать для каждого варианта, более очевидно, это не сработает. Как уже упоминалось в комментариях @roe, здесь используются глобальные цвета, которые часто осуждаются.
Альтернативой является определение класса с write
метод и переопределить это в подклассах Red
а также Blue
поступать правильно
Будет ли это лучше, чем предложенное вами решение, зависит от вашей конкретной ситуации.
Как я уже сказал, это здорово. Единственное, что я могу добавить к вашему решению, это то, что, возможно, лучше colors
,
function write(what) {
var colors = [];
colors['Blue'] = function() { alert('Blue'); };
colors['Red'] = function() { alert('Red'); };
colors[what]();
}