2012-02-18 14 views
16

Mam kilka przydatnych funkcji, które zebrałem podczas całego mojego życia.Jak łączyć funkcje bez użycia prototypu?

function one(num){ 
    return num+1; 
} 

function two(num){ 
    return num+2; 
} 

mogę nazwać je two(two(one(5)))

Ale wolałbym używać (5).one().two().two()

W jaki sposób można to osiągnąć bez użycia prototyp?

Próbowałam zobaczyć, jak podkreślają dzieła łańcuchowe, ale ich kod jest zbyt intensywny, aby zrozumieć, że

+1

tylko dla przypomnienia, tak, to są funkcje, które kolekcjonowałem ... – mithril333221

Odpowiedz

22

Składnia kropka jest zarezerwowana dla obiektów. Możesz zrobić coś takiego, jak

Lub zamierzasz wdrożyć te metody na prototypie natywnego obiektu/funkcji Number. Które pozwoliłyby (5).one()...

+0

Oczywiście powinieneś zaimplementować rzecz 'MyNumber' również z prototypami, ponieważ jest znacznie wydajniejsza. – Bergi

+0

"ValueOf()" jest konieczne ?, mam na myśli, czy zawsze powinienem zakończyć moje łańcuchy z jakąś funkcją, która zwraca wartość val? – mithril333221

+0

@ mithril333221 - aby tworzenie łańcucha działało, wartość zwracana z każdej metody MUSI być obiektem odpowiedniego typu. Jeśli chcesz czegoś innego niż poza obiektem, musisz wywołać metodę, aby uzyskać te informacje. – jfriend00

4

Miła i ogólne alternatywą jest stworzenie funkcji niestandardowych złożenie funkcji

var go = function(x, fs){ 
    for(var i=0; i < fs.length; i++){ 
     x = fs[i](x); 
    } 
    return x; 
} 

można nazwać tak:

go(5, [one, two, two]) 

nie jestem osobiście wielkim fanem metody łańcuchowanie, ponieważ ogranicza cię do predefiniowanego zestawu funkcji i istnieje rodzaj niedopasowania impedancji między wartościami wewnątrz "obiektu wiążącego" a wartościami swobodnymi na zewnątrz.

+0

Chcę wiedzieć, jakie ograniczenia są określone – mithril333221

+0

Chodzi mi o to, że jeśli chcesz zastosować metodę "łączenia łańcuchów", musisz wiedzieć, co wszystkie łańcuchowe metody będą zdefiniowane podczas definiowania łańcucha (ponieważ musisz dodać metodę do prototypu łańcucha dla każdej funkcji) Z drugiej strony, funkcja składu funkcji nie musi znać wcześniejszych funkcji, więc możesz przekazać cokolwiek chcesz – hugomg

+0

Nadal można dodawać funkcje do prototypu za każdym razem, gdy ich potrzebujesz, problem polega tylko na tym, że muszą one pasować do konstrukcji łańcucha z 'return this' i użyć' this.value'. że biblioteka może zanieczyścić globalny obszar nazw, a przestrzeń nazw, aby je połączyć, sprawia, że ​​składnia kompozycji staje się trudniejsza: – Bergi

6

Aby uniknąć konieczności wywoływania numeru toValue na końcu łańcucha, jak w przypadku rozwiązania @ Bergi, można użyć funkcji z dołączonymi metodami. JS zadzwoni pod numer toValue automatycznie, gdy spróbuje przekonwertować na niego typ pierwotny.

function MyNumber(n) { 
    function x() { } 
    x.one = function() { n++; return this; }; 
    x.valueOf = function() { return n; }; 
    return x; 
} 

Następnie

MyNumber(5).one().one() 
> 7 
0

Inną alternatywą jest użycie lodash flow funkcji. Na przykład:

var five = _.flow(one, two, two) 
five(5) 

Wolę przypisywać nowy łańcuch do zmiennej. Daje to jasną nazwę i zachęca do ponownego użycia.

Btw, lodash pomaga również przekazywać dodatkowe argumenty do funkcji łańcucha. Na przykład:

var addFive = _.flow(
    _.partialRight(_.add, 1), 
    _.partialRight(_.add, 2), 
    _.partialRight(_.add, 2) 
) 

Istnieje wiele innych użytecznych funkcji pomocnych w szeregowaniu funkcjonalnej, np częściowy, rozprzestrzeniać, klapki, negować itd

Powiązane problemy