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

5 minutos de lectura

avatar de usuario
soy solo yo

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

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

Por lo que sé, el encadenamiento es una de las ventajas frente a otros marcos famosos. ¿Puede alguien explicarme cómo funciona el encadenamiento aquí?

  • Ninguna de las respuestas a continuación está completa, consulte la documentación en .end(): api.jquery.com/endya que jQuery no solo devuelve el objeto en el que está operando una función, sino que si el selector se cambia a mitad de la cadena, también conserva el historial de los selectores utilizados para que pueda “volver” a un selector utilizado anteriormente.

    – OVN

    19 de septiembre de 2011 a las 18:16


  • Aquí está el patrón de diseño: en.wikipedia.org/wiki/Fluent_interface

    – José

    19 de septiembre de 2011 a las 18:42

  • @Vibhu: OP quiere saber cómo funciona el encadenamiento, no todos los detalles de la implementación de jQuery. “…para un programador novato como yo, estoy seguro de que hay alguien que me puede dar una explicación que me permita entender cómo funciona el encadenamiento”.

    – usuario113716

    19 de septiembre de 2011 a las 19:58

  • Obtuve muy buenas respuestas! gracias a todos.

    – soy solo yo

    19 de septiembre de 2011 a las 21:11

  • posible duplicado de ¿Cómo funciona el encadenamiento básico de objetos/funciones en javascript?

    – Bergi

    11 de junio de 2014 a las 14:44

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();

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

  • En vez de return objpuedes decir return this? Porque probé y me da el mismo resultado.

    – Derek 朕會功夫

    4 de enero de 2012 a las 3:28

  • @Derek: Podrías hacer eso, porque this en las funciones del ejemplo será el objeto al que se invocó cada método.

    usuario1106925

    4 de enero de 2012 a las 3:36

  • @Derek朕會功夫 Creo que para las personas que son nuevas en JavaScript, la forma de hacerlo de @squint responde (devolviendo una referencia a una variable en lugar de this) es más claro porque var that = this En mi experiencia, parece alejar a las personas de querer aprender a programar, y piensan que es difícil. Pero creo que su sugerencia es más clara porque hace que sea más obvio cómo podría implementar múltiples “profundidades” de cadenas

    – tacos_tacos_tacos

    31 de julio de 2015 a las 8:04

  • cómo funciona el acceso a una matriz similar, $('a')[0] da el primer elemento

    – Muhammad Umer

    12/10/2015 a las 21:50

  • Dado que esas funciones contienen ‘obj’ en su alcance de cierre, ¿no crea esto una referencia circular? Devolver ‘esto’ evita ese problema, por lo que probablemente sea lo que debería hacer.

    – Dave Braton

    27 de febrero de 2018 a las 23:41

avatar de usuario
Tejas

Todo lo que está haciendo es devolver una referencia a this cuando finaliza el método. Tome este objeto simple por ejemplo:

 var sampleObj = function()
 {
 };

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

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

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

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

Básicamente la primera llamada de 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;
}

  • Encuentro que esto explica cómo funciona más que la respuesta aceptada.

    – K3NN3TH

    12/08/2015 a las 20:59

return $this;

cada función jQuery devuelve una instancia de la clase jQuery, a la que luego se le pueden llamar métodos. podría desglosarlo, y este código tendría el mismo efecto.

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

avatar de usuario
pimvdb

El punto es que una función debe evaluar a la función “principal”. Entonces, por ejemplo

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

tiene que evaluar a:

foo().test();

para que pueda llamar a otra función en 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;
}

Después,

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

Y debido a esto:

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

Entonces porque something.bar() evalúa a somethingpuede llamar inmediatamente a la segunda función de una sola vez.

Al encadenar la función/método principal, se devuelve un objeto que luego es utilizado por la función/método secundario, y las cosas continúan de esa manera. en resumen el jQuery o $ se devuelve a sí mismo (un objeto) que permite el encadenamiento.

Es el mismo mecanismo de abajo.

var obj=$('input');    //returns jQuery object
var obj1=obj.val('a'); //returns jQuery object
var obj2=obj1.fadeOut();//returns jQuery object

Se ve así si se hace con encadenamiento

$('input').val('a').fadeOut();

avatar de usuario
Himanshu

Aquí hay un ejemplo de encadenamiento de devolución de llamada condicional, como se usa en el $.ajax Función jQuery.

// conditional callback function example
myFunction = function () {

    // define event callback prototypes without function parameter
    var callback_f = new Object;
    callback_f.callback1 = function () { return callback_f; };
    callback_f.callback2 = function () { return callback_f; };

    if ([condition]){
        // redefine the callback with function parameter 
        // so it will run the user code passed in
        callback_f.ReturnPlayer = function (f) { f(); return callback_f; };
    }else{ 
        callback_f.NewPlayer = function (f) { f(); return callback_f; };
    }

    return callback_f;
}

¿Ha sido útil esta solución?