¿Cómo funciona el encadenamiento de objetos o métodos en jQuery?

Resuelto isJustMe asked hace 13 años • 10 respuestas

No estoy preguntando cuál es la sintaxis apropiada para encadenar, sé que podría ser algo como:

$('myDiv').removeClass('off').addClass('on');

Hasta donde yo sé, el encadenamiento es una de las ventajas frente a otros marcos famosos. ¿Alguien puede explicarme cómo funciona el encadenamiento aquí?

isJustMe avatar Sep 20 '11 01:09 isJustMe
Aceptado

Si tiene un objeto con ciertos métodos, si cada método devuelve un objeto con métodos, simplemente puede llamar a un método desde el objeto devuelto.

var obj = {   // every method returns obj---------v
    first: function() { alert('first');   return obj; },
    second: function() { alert('second'); return obj; },
    third: function() { alert('third');   return obj; }
}

obj.first().second().third();

DEMOSTRACIÓN: http://jsfiddle.net/5kkCh/

user113716 avatar Sep 19 '2011 18:09 user113716

Todo lo que hace es devolver una referencia a thiscuándo finaliza el método. Tomemos este objeto simple, por ejemplo:

 var sampleObj = function()
 {
 };

 sampleObj.prototype.Foo = function()
 {
     return this;
 };

Podrías encadenar estas llamadas todo el día porque devuelves una referencia a this:

var obj = new sampleObj();
obj.Foo().Foo().Foo().Foo() // and so on

jQuery simplemente realiza una operación y luego devuelve this.

Tejs avatar Sep 19 '2011 18:09 Tejs

Básicamente, la primera llamada a la función $('myDiv')devuelve un objeto jQuery, luego cada llamada posterior devuelve el mismo.

Flojamente,

var $ = function(selector) {
   return new jQuery(selector);
};

jQuery.prototype.removeClass = function(className) {
   // magic
   return this;
}
Daniel A. White avatar Sep 19 '2011 18:09 Daniel A. White
return $this;

cada función jQuery devuelve una instancia de la clase jQuery, que luego puede tener métodos llamados. podrías descomponerlo y este código tendría el mismo efecto.

jQuery_obj = $('myDiv');
jQuery_obj = jQuery_obj.removeClass('off');
jQuery_obj = jQuery_obj.addClass('on');
GSto avatar Sep 19 '2011 18:09 GSto

El punto es que una función debe evaluarse como la función "principal". Entonces, por ejemplo

foo().bar().test();

tiene que evaluar para:

foo().test();

para que puedas llamar a otra función foo(). Para hacer esto, puedes return this:

function foo() {
    // empty, nothing interesting here
}

foo.prototype.bar = function() {
    return this;
}

foo.prototype.test = function() {
    return this;
}

Entonces,

var something = new foo();
something.bar() === something; // true

Y a causa de esto:

something.bar().test() === something.test(); // true

Entonces, como something.bar()se evalúa como something, puedes llamar inmediatamente a la segunda función de una sola vez.

pimvdb avatar Sep 19 '2011 18:09 pimvdb