2010-02-21 11 views
19

nie chcę użyć przełącznika w moim kodu, więc szukam jakiegoś alternatywnegoAlternatywa dla „switch” oświadczenie

Przykład z przełącznika:

function write(what) { 

    switch(what) { 

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

    ... 

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

    } 

} 

przykładu bez przełącznika :

colors = []; 

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


function write(what) { 

    colors[what](); 

} 

moje pytania są następujące:

  1. Czy znasz inne alternatywy?
  2. Czy to najlepsze rozwiązanie?
+6

To świetnie. Zostaw to. – codeholic

+2

tak, to lepsze rozwiązanie z mniejszym kodem :) – Sarfraz

+0

To byłaby moja droga. – brian

Odpowiedz

19

mam tylko notatkę o swoim drugim podejściu, to shouldn't use an Array do przechowywania indeksów nienumeryczne (który można by nazwać w innych językach jest asocjacyjną).

Powinieneś użyć prostego obiektu.

Ponadto, warto sprawdzić, czy what argument przekazany do funkcji write występuje jako własność swojego obiektu colors i sprawdzić, czy jest to funkcja, dzięki czemu można wywołać go bez błędów Run-Time:

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

Z szacunkiem, myślę, że artykuł, który łączyłeś, źle to zrobił. Raczej nie należy używać dla ... in do iterowania tablicy. –

+1

@machine: Ten artykuł mówi również o wyrażeniu 'for ... in' i problemach, które pojawiają się, gdy prototypowy element wbudowanych konstruktorów, takich jak' Array' i 'Object', został rozszerzony, ale w dolnej linii artykułu jest to, że * tablice JavaScript mają być numeryczne * i są często używane do przechowywania dowolnych par klucz/wartość, co jest złym zwyczajem ... – CMS

+0

Dolna linia? Używanie właściwości expando w tablicy nie zmienia tego faktu. Nie ma nic do zyskania, przekształcając jeden z najbardziej wszechstronnych obiektów do swojej dyspozycji w najmniej wszechstronny. Nie jestem pewien, dlaczego mówisz "Artykuł również mówi" ... Rozumiem, że cały punkt artykułu polega na "lepszym" wspieraniu używania for..in z tablicami. –

0

Alternatywnym rozwiązaniem jest zdefiniowanie klasy z metodą write i zastąpić że w podklasach Red i Blue aby zrobić dobry uczynek.

To, czy jest lepsza niż proponowane rozwiązanie, zależy od konkretnej sytuacji.

0

Już prawie jesteś. Jeśli to możliwe, możesz dodać funkcję pomocnika, aby ułatwić konfigurację. Na przykład:

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

EDIT:
Jeśli to, co chcesz zrobić dla każdej z opcji jest bardziej skomplikowana, wyraźnie to nie będzie działać. Jak wspomniano w komentarzach @roe, używa on globalnych kolorów, które często są mile widziane.

+0

Świetny pomysł! Dziękuję Ci. – Bambert

+2

Działa to tylko w tym konkretnym przypadku, są szanse, że nie mają tak wiele wspólnego w rzeczywistości. Również kolory są tutaj globalne, co rzadko jest Dobrą Rzeczą. – falstro

+0

Będę edytować odpowiedź, aby była bardziej widoczna. – smaclell

1

Pytanie 2:

Generalnie, jeśli można zastąpić struktury sterujące zwyczaj z tego słownika, jesteś idealny. Jest łatwy do odczytania i bardzo elegancki - trzymaj się go.

0

Jak już powiedziałem, jest świetnie. Jedyną rzeczą, którą mogę dodać do twojego rozwiązania jest to, że być może lepiej jest zlokalizować twój colors.

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

można używać literały obiektowe i spróbuj złapać pułapkę domyślne:

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'); 
5

użyłem strukturę jak ten dzisiaj:

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

Podoba mi się, że to naprawdę niewielka ilość kodu do wyboru łańcucha na podstawie wyboru.

Można również przekazać go do funkcji:

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

krótkie i proste, jak to. +1 – schellmax

+0

to jest fajne, o ile wybrany kolor istnieje w colorString. jeśli selectedColor jest na przykład "pomarańczowy", otrzymasz błąd typu. – northamerican

+1

W rzeczywistości można łatwo dodać domyślną opcję z '({'czerwony':" kolor jest czerwony "}) [selectedColor] || "default" " – superzamp

1

musiałem zrobić zrobić porównanie na rodzaj grupowej podpór obiektu dla listy i nie chce zrobić przełącznik/przypadek dla wszystkich możliwości, więc najpierw przydzieliłem tablicę przydziałów do numerycznej pozycji, więc sprawa stała się prostym porównaniem. To jest tylko 4 możliwości ale masz dryfu jak rozszerzyć to do sytuacji, w której przełącznik/przypadek staje się niewykonalna:

funkcji mySort2 (ITEM1, ITEM2) {

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

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

// jeśli to możliwe złe dane trzeba to najpierw sprawdzić?

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; 

}

+0

Jest to odpowiedź: alternatywa dla użycia przełącznika/obudowy do tego celu. Możesz również użyć [] z [], aby mieć rzeczywistą macierz wartości do zwrócenia. – Icedvolvo