2011-10-11 12 views
15

Pozwala funkcję wyobrazić tak:Jak zrobić funkcję łańcuchową w JavaScript?

function foo(x) { 
    x += '+'; 
    return x; 
} 

Wykorzystanie byłoby jak:

var x, y; 
x = 'Notepad'; 
y = foo(x); 
console.log(y); // Prints 'Notepad+'. 

szukam sposobu na stworzenie funkcji, która jest chainable z innymi funkcjami.

Wyobraź Wykorzystanie:

var x, y; 
x = 'Notepad'; 
y = x.foo().foo().toUpperCase(); // Prints 'NOTEPAD++'. 
console.log(y); 

Jak to zrobić?

Odpowiedz

14

Jasne, sztuką jest zwrócić przedmiot raz skończysz modyfikując go:

String.prototype.foo = function() { 
    return this + "+"; 
} 

var str = "Notepad"; 
console.log(str.foo().foo().toUpperCase()); 

http://jsfiddle.net/Xeon06/vyFek/

Aby metoda dostępna na String, jestem modyfikując to prototyp. Uważaj jednak, aby tego nie robić na Object, ponieważ może to powodować problemy przy wyliczaniu ich właściwości.

+3

dobrze jest przynajmniej sprawdzić właściwość natywnych typów przed jej dodaniem, np. 'If (! ('Foo' w String.prototype)) {String.prototype.foo = function() {.. .}} ' – keeganwatkins

+0

Jeśli chcesz rozszerzyć obiekt bez zrywania wyliczenia, użyj (semi-modern) [' Object.defineProperty'] (https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/ Object/defineProperty): Object.defineProperty (String.prototype, {value: function() {return this + "+";}}) ". Domyślnie flaga 'wyliczalna' jest ustawiona na 'fałsz'. – Phrogz

+0

@keeganwatkins tak to jest :). Zakładam, że OP tylko pytał o ciągi jako przykład, więc ograniczyłem ostrzeżenia do minimum, ale to jest dobra uwaga. –

6

Jeśli dobrze pamiętam, możesz użyć "this" jako kontekstu funkcji (obiektu, do którego należy) i zwrócić ją, aby funkcja mogła działać w łańcuchu. Innymi słowy:

var obj = 
{ 
    f1: function() { ...do something...; return this;}, 
    f2: function() { ...do something...; return this;} 
} 

następnie można łańcucha wywołania jak obj.f1().f2()

Należy pamiętać, że nie będzie w stanie osiągnąć to, czego oczekują, wywołując obj.f1() toUpperCase(). - wykona f1(), zwróci "to" i spróbuje wywołać obj.toUpperCase().

Powiązane problemy