2011-10-11 24 views
15

Lets funzione immaginare come questo:Come rendere la funzione concatenabile in JavaScript?

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

L'utilizzo di come sarebbe stato:

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

Sto cercando un modo per creare la funzione che è chainable con altre funzioni.

Immaginate utilizzo:

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

Come faccio a fare questo?

risposta

14

Certo, il trucco è quello di restituire l'oggetto una volta che hai finito modificarlo:

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

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

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

Per rendere il metodo accessibile String, sto modificando è prototipo. Fare attenzione a non farlo su Object, poiché può causare problemi durante l'enumerazione delle proprietà.

+3

è una buona idea controllare almeno una proprietà sui tipi nativi prima di aggiungerla, ad esempio 'if (! ('Pippo' in String.prototype)) {String.prototype.foo = function() {.. .}} ' – keeganwatkins

+0

Se si desidera estendere un oggetto senza interrompere l'enumerazione, utilizzare il (semi-moderno) [' Object.defineProperty'] (https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/ Object/defineProperty): 'Object.defineProperty (String.prototype, {value: function() {return this +" + ";}})'. Di default il flag 'enumerable' è impostato su' false'. – Phrogz

+0

@keeganwatkins si è :). Presumo che l'OP chiedesse solo delle stringhe come esempio, quindi ho mantenuto gli avvertimenti al minimo, ma questo è un buon punto. –

6

Se ricordo correttamente, è possibile utilizzare "questo" come contesto di una funzione (oggetto a cui appartiene) e restituirlo per rendere concatenabile la funzione. In altre parole:

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

allora è possibile concatenare le chiamate come obj.f1().f2()

tenere a mente, non sarà in grado di realizzare ciò che si aspettano chiamando obj.f1() toUpperCase(). - eseguirà f1(), restituirà "this" e proverà a chiamare obj.toUpperCase().

Problemi correlati