2011-10-11 7 views
15

Lets función imaginar como esto:¿Cómo hacer función encadenable en JavaScript?

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

uso de ella sería como:

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

Busco una forma de crear la función que está en cadena con otras funciones.

Imagínese uso:

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

¿Cómo voy a hacer esto?

Respuesta

14

Claro, el truco consiste en devolver el objeto una vez que haya terminado de modificarlo:

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

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

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

Para que el método disponible en String, estoy modificando su prototipo. Tenga cuidado de no hacer esto en Object, ya que puede causar problemas al enumerar sus propiedades.

+3

es una buena idea comprobar al menos una propiedad en los tipos nativos antes de agregarla, es decir, 'if (! ('Foo' en String.prototype)) {String.prototype.foo = function() {.. .}} ' – keeganwatkins

+0

Si desea extender un objeto sin romper la enumeración, use el (semi-moderno) [' Object.defineProperty'] (https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/ Object/defineProperty): 'Object.defineProperty (String.prototype, {value: function() {return this +" + ";}})'. Por defecto, el indicador 'enumerable' se establece en' false'. – Phrogz

+0

@keeganwatkins si, es :). Supongo que el OP solo estaba preguntando sobre las cadenas como ejemplo, así que mantuve las advertencias al mínimo, pero ese es un buen punto. –

6

Si mal no recuerdo, puede usar "this" como contexto de una función (objeto a la que pertenece) y devolverla para que la función se pueda encadenar. En otras palabras:

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

continuación, se pueden encadenar las llamadas como obj.f1().f2()

Tenga en cuenta, usted no será capaz de lograr lo que se esperaba llamando obj.f1() toUpperCase(). - ejecutará f1(), devolverá "this" e intentará llamar a obj.toUpperCase().

Cuestiones relacionadas