Professional Documents
Culture Documents
Page 1 of 26
jQuery vs MooTools
May, 2009 - Aaron Newton of Clientcide (http
Also available in Portuguese (Brazil) (/index_pt-br.html), Chinese (/index_cn.html), Farsi (Persian) (index_fa.html) and English translation (http://wiki.github.c
La mayora de la gente que comienza con JavaScript en estos das se encuentra con la desafiante tarea de la eleccin de la biblioteca a usar, o al menos cual aprender primero. Si estas trabajando para una empresa, probablemente ellos ya han elegido un framework por t, siendo este caso algo que se puede debatir. Si esta es la situacin y ellos eligieron MooTools (http://www.mootools.net) y tu usas normalmentejQuery (http://www.jquery.com), este artculo te puede ser ande utilidad. Cada (http://twitter.com/joshink/statuses/1671986611) da (http://twitter.com/jezusisstoer/statuses/1642244246) en
(http://twitter.com/digitalcampaign/statuses/1622094648) twitter (http://twitter.com/jesswma/statuses/1605733380) veo numerosos posts que caen en
Sobre el Autor
Soy un programador de MooTools. Trabajo en el framework de MooTools. Escribo sobre MooTools. Yo escribel principal tutorial online (http://www.mootorial.com) y el libro sobre MooTools (http://www.amazon.com/gp/product/1430209836?
ie=UTF8&tag=clientside20&link_code=as3&camp=211189&creative=373489&creativeASIN=1430209836).
Obviamente, tengo una perspectiva que es algo tendenciosa. Aclarare tambin que no uso jQuery muy a menudo. Si eres un programador de jQuery y ves algo que yo he presentado mal aqu, por favor, contctame y aydame a corregir el incidente. Mi objetivo aqu es ofrecer ayuda y ser conciso para los dems - no intento vender un framework sobre otro.
http://jqueryvsmootools.com/index_es-ar.html
16/07/2010
Page 2 of 26
Sobre el tradutor
Usuario de MooTools, jQuery y de Ruby On Rails
(http://www.workingwithrails.com/person/7271-pedro-visintin). Utilizo Clientcide
Propsito
Ayudarte a hacer una eleccin entre estos dos frameworks me implica mostrarte en qu y cmo difieren los mismos. Comenzar diciendo que ambos son elecciones excelentes. No puedes hacer una eleccin incorrecta en estas opciones. Ambos frameworks tienen sus fortalezas y debilidades, pero, en general ambos son excelentes opciones. Hay otros frameworks que merecen ser evaluados tambin. Dojo (http://www.dojotoolkit.org/), Prototype (http://www.prototypejs.org/), YUI (http://developer.yahoo.com/yui/), Ext (http://extjs.com/) y otros son todos excelentes opciones. Cual elijas tiene ms relacin con tu propio estilo y cual es el problema a resolver. El objetivo de este artculo es enfocarnos en MooTools y jQuery, viendo el incremento de la consideracin de estos dos frameworks por la gente. Finalmente, no estoy tratando de convencer a nadie de cambiar de un framework al otro. Hay cosas interesantes de estos dos frameworks de las cuales puedes aprender. Puedes leer un poco ms sobre este artculo y porqu lo escrb en mi entrada en el blog de Clientcide donde lo he anunciado (http://www.clientcide.com/3rd-partylibraries/jquery-vs-mootools-mootools-vs-jquery/).
Contenidos
Los Definiciones lo dicen todo (#mottos) La Curva de Aprendizaje y La Comunidad (#learning) Para qu es bueno JavaScript (#javascript) Ms que solo el DOM (#dom) Herencia con JavaScript (#inheritance) Auto Referencia (#self) MooTools Hace JavaScript en s Ms Divertido (#jsfun) jQuery Hace el DOM Ms Divertido (#domfun) Cualquier cosa que hagas yo lo puedo hacer mejor (#cando) MooTools te permite tenerlo a tu manera (#yourway) Encadenado (Chaining) como un patrn de diseo (#chaining) Reusando cdigo con jQuery (#reuse) Reusando cdigo con MooTools (#classes) MooTools y Herencia (#mooinheritance) Extendiendo e Implementando Clases (#extension)
http://jqueryvsmootools.com/index_es-ar.html
16/07/2010
Page 3 of 26
Las Estadsticas
jQuery Core Tamao de 55.9K la biblioteca Licencia MIT & GPL (http://en.wikipedia.org/wiki/GPL) Utilidades del DOM s s s s s (un subset) s 64.3K Prestaciones MIT
(http://en.wikipedia.org/wiki/MIT_License) (http://en.wikipedia.org/wik
MooTools Cor
Extensiones una docena aprox. para Array, Object, y String como seis docenas, para Array Natovas Function, y Number (excluyendo Element) Herencia No soportada directamente con jQuery Provista con el constructorCla
(http://mootools.net/docs/co
Biblioteca de UI Oficial
no
Informacin basada en datos obtenidos dejquery.com (http://jquery.com), mootools.net (http://mootools.net), y wikipedia.com (http://en.wikipedia.org/wiki/Comparison_of_JavaScript_frameworks).
http://jqueryvsmootools.com/index_es-ar.html
16/07/2010
Page 4 of 26
jQuery es una Biblioteca de JavaScript rpida y concisa que simplifica el recorrido, manejo de eventos, animacin, y interacciones Ajax en el documento HTML para un rpido desarrollo web. jQuery est diseado para cambiar la manera que tu escribes JavaScript.
MooTools es un compacto, modular, Object-Oriented JavaScript framework diseado para el programador JavaScript intermedio a avanzado. Este permite escribir un cdigo potente, flexible, y cross-browser con su elegante, bien documentada y coherente API.
Yo pienso que esto realmente lo resume. Si tu me preguntas (y ests leyendo esto, por lo que asumir que lo ests haciendo), la pregunta no es sobre cual framework es mejor o peor. La pregunta es, cuales de estas cosas tu quieres hacer? Estos dos frameworks no estn tratando de hacer las mismas cosas. Ellos se sobreponen en la funcionalidad que proveen, pero no estn tratando de hacer las mismas cosas. La descripcin de jQuery's de si mismo habla sobre HTML, eventos, animaciones, Ajax, y desarrollo web. MooTools habla sobre orientacin a objetos y sobre escribir codigo potente y flexible. jQuery aspira a "cambiar la forma que tu escribes JavaScript" mientras que MooTools est diseado para el programador JavaScript intermedio y avanzado. Parte de esta consideracin es la nocin de un framework vs un toolkit. MooTools es un framework que intenta implementar JavaScript como deberia ser (de acuerdo a los autores de MooTools). El objetivo es implementar un API que se percibe como JavaScript y mejora todo; no solo el DOM. jQuery es un toolkit que te brinda una coleccin de mtodos de fcil uso en un sistema autocontenido y diseado para hacer el DOM en si mismo ms amigable. Sucede que la mayora se enfoca en el DOM cuando escribe JavaScript, entonces en muchos casos, jQuery es todo lo que necesitas. La mayor parte del cdigo cuando escibes usando MooTools se sigue percibiendo como JavaScript. Si no ests interesado en JavaScript como un lenguaje, aprender MooTools se convertir en una tarea pesada y no algo placentero. Si ests interesado en JavaScript y lo que lo hace interesante, poderoso, y expresivo, entonces, personalmente, yo pienso que MooTools es la mejor opcin.
http://jqueryvsmootools.com/index_es-ar.html
16/07/2010
Page 5 of 26
Numbers
(https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Global_Objects/Nu
Functions
(https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Global_Objects/Fu
Arrays
(https://developer.mozilla.org/En/Core_JavaScript_1.5_Reference/Global_Objects/Ar
Dates
(https://developer.mozilla.org/En/Core_JavaScript_1.5_Reference/Global_Objects/Da
http://jqueryvsmootools.com/index_es-ar.html
16/07/2010
Page 6 of 26
Regular Expressions
(https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Global_Objects/Re
y ms. JavaScript tambin te brinda un modelo de herencia - una especie de modelo esotrico llamado prototypal inheritance (https://developer.mozilla.org/en/Core_JavaScript_1.5_Guide/Inheritance) (de lo cual voy a profundizar ms adelante). Estos bloques de construccin y el concepto de herencia son el pan y la manteca de cualquier lenguaje de programacin y nada tienen que ver con los browsers o la web o CSS o HTML. Puedes escribir cualquier cosa que quieras en JavaScript. Ta-te-ti, ajedrez, edicin de fotos, un web server, cualquier cosa. Sucede que el 99% de todo el JavaScript que anda por ah se ejecuta en browsers y eso es como lo pensamos que es. El lenguaje de programacin para los browsers. Entendiendo que el browser, el DOM, es solo donde acostumbramos a usar JS la mayoria del tiempo pero saber que JS es actualmente un muy robusto y expresivo lenguaje de programacin, te ayudar a entender la diferencia entre MooTools y Jquery.
http://jqueryvsmootools.com/index_es-ar.html
16/07/2010
Page 7 of 26
de strings, fechas, expresiones regulares, arrays y funciones, tu puedes. No es el trabajo de jQuery ayudarte a hacerlo. JavaScript como lenguaje est ahi a tus pies. jQuery hace del DOM su cancha de juego, pero el resto de JavaScript no est en su alcance. Aqu es donde MooTools es ampliamente diferente. En vez de enfocarse exclusivamente en el DOM (ms exactamente, como veremos en breve, este ofrece toda la funcionalidad que jQuery tiene pero lo alcanza de una muy diferente manera), MooTools toma dentro de su alcance el lenguaje completo. Si jQuery hace del DOM su cancha de juego, MooTools intenta hacer a JavaScript su cancha de juego, y esa es una de las razones por la cuales es mas dificil de aprender.
es particularmente nico pero es bastante poco comn en lenguajes de programacin. En vez de clases que son definidas y pueden tener subclases ste pasa los comportamientos a travs de herencia prototipada (prototypal inheritance) (http://en.wikipedia.org/wiki/Prototype-based_programming). Esto significa que los objetos heredan directamente de otros objetos. Si referencias una propiedad de un objeto que hereda de otro objeto, el lenguaje inspecciona el objeto hijo por esa propiedad y, si no la encuentra, busca a ella en el padre. De esta manera es como trabaja un array. Cuando tipeas: [1,2,3].forEach(function(item) { alert(item) }); //esto hace alert el mtodo "forEach
(https://developer.mozilla.org/En/Core_JavaScript_1.5_Reference:Objects:Array:forE
no es una propiedad del array que declaraste ([1,2,3]), este es una propiedad del
http://jqueryvsmootools.com/index_es-ar.html
16/07/2010
Page 8 of 26
prototipo para todos los Arrays. Cuando referencias este mtodo el lenguaje busca un mtodo llamado forEach en tu array, y, si no lo encuentra, busca entonces en el prototipo de todos los arrays. Esto significa que el mtodo forEach no est en memoria por cada array existente; ste est solo en la memoria del prototipo de arrays. Esto es increiblemente eficiente y bastante potente. (Nota: MooTools hace un alias de el metodo forEach llamndolo each)
Autoreferencia
Javascript tiene una palabra especial: "this". Esto es dificil para mi definir en forma resumida de que se trata este "this", por defecto, "this" es el objeto del cual se asocia el mtodo corriente. Este permite a los objetos referise a si mismos, ya que de otro modo no tendran la forma para hacerlo. Esto se vuelve importante cuando creas objetos hijos y tienes numerosas instancias de ese objeto; de qu otra manera el mtodo de un objeto podria referise a s mismo? Cuando la copia actual del mtodo existe en el objeto padre, no en el hijo, la palabra "this" permite a estas instancias referirse a su propio estado. (aqu hay una descripcion mucho ms completa sobre la palabra "this" (http://www.quirksmode.org/js/this.html), y otra de Mozilla
(https://developer.mozilla.org/En/Core_JavaScript_1.5_Reference/Operators/Special
La palabra "this" permite a los objetos que heredan de otros objetos referirse a si mismos, pero hay veces donde quieres que se referencie a algo mas a travs de "this". Esto es llamado binding (http://alternateidea.com/blog/articles/2007/7/18/javascript-scope -and-binding), en donde especificas un "this" different para un mtodo. El mtodo "each" en un Array te permite especificar el objeto que ser retornado cuando utilices "this" como segundo argumento. Aqu hay un ejemplo de donde deseamos usar un "this" diferente: var ninja = { weapons: ['katana', 'throwing stars', 'exploding palm technique log: function(message) { console.log(message); }, logInventory: function() { this.weapons.each(function(weapon) { //queremos que "this" est apuntando a ninj this.log('this ninja can kill with its ' + weapon); }, this); //entonces pasamos "this" (que es ninja) al mtod } }; ninja.logInventory();
http://jqueryvsmootools.com/index_es-ar.html
16/07/2010
Page 9 of 26
//this ninja can kill with its katana //this ninja can kill with its throwing stars //this ninja can kill with its exploding palm technique En el ejemplo anterior, nosotros enlazamos o asociamos (bound) ninja (el cual es "this" dentro de el mtodo logInventory) al mtodo que pasamos al array de esta manera podremos hacer referencia a la propiedad de log de ninja. Si no hicieramos esto "this" ser window. Estos son solo algunos ejemplos del poder y expresividad que JavaScript tiene para ofrecer - herencia, autoreferencia y enlace o asociacin, y eficientes propiedades de prototipos. Las malas noticias es que el viejo JavaScript bsico, no hace accessibles ni tiles estas poderosas cosas, y aqu es donde MooTools comienza. MooTools hace que estos tipos de patrones sean fciles y porqu no placenteros de usar. Terminars escribiendo cdigo ms abstracto, y en el largo plazo, esto es algo bueno - algo potente. Aprendiendo como estos patrones son valiosos y como usar ellos apropiadamente lleva esfuerzo, pero el lado bueno es que el cdigo que escribes es altamente reusable y mucho ms facil de mantener. Voy a hablar de estas dos cosas en un poco mas de un minuto.
http://jqueryvsmootools.com/index_es-ar.html
16/07/2010
Page 10 of 26
JavaScript mas divertido, jQuery intenta hacer el DOM ms divertido y los diseadores han elegido limitar su alcance para esa tara.
tutorial de MooTools (http://www.mootorial.com/wiki)(ambos escritos por mi) ellos comienzan en un lugar muy diferente. Mientras puedes saltar adelante y rpidamente aprender los efectos y el DOM, si quieres aprender MooTools, tendras que empezar con cosas como Class, y, debo admitir: si sos nuevo en programacion, o simplemente quieres algo funcionando en tu sitio sin tener que aprender todo de JavaScript, jQuery te parecer mucho ms amigable. Del otro lado, si quieres aprender JavaScript, MooTools es una excelente manera de hacerlo. Implementa un monton de cosas que JavaScript tendr (muchos de los mtodos en Natives son simplemente los de la especificacin JavaScript 1.8 (https://developer.mozilla.org/En/New_in_JavaScript_1.8) y posteriores). Si estas acostumbrado a programar, especialmente de ambas maneras, orientado a objetos y programacin funcional, MooTools tiene un montn de patrones de diseo que son muy interesantes y expresivos.
http://jqueryvsmootools.com/index_es-ar.html
16/07/2010
Page 11 of 26
http://jqueryvsmootools.com/index_es-ar.html
16/07/2010
Page 12 of 26
window.addEvent('domready',function() { $$('#orderedlist li:last-child').addEvents({ mouseenter: function() { this.addClass('green'); }, mouseleave: function() { this.removeClass('green'); } }); }); De nuevo, muy similares. Debo mostrar que la versin de MooTools es ms explcita, pero tamben ms verborrgica a causa de ello. Queda claro leyendo el cdigo de MooTools que estamos agregando dos eventos - uno para cuando el mouse entra y otro cuando el mouse sale, mientras que la versin de jQuery es ms concisa; su mtodo hover (http://docs.jquery.com/Events/hover) acepta dis mtodos - el primero para cuando el mouse entra y otro para cuando sale. Me gusta mas, personalmente, el hecho de que el cdigo de MooTools es ms legible pero esa es una observacin muy subjetiva. Voy a decir que jQuery a veces puede volverse demasiado esotrico para mi gusto. Los mtodos no siempre me transmiten sobre qu hacen cuando los miro y lo encuentro dificil para recorrerlos. Esto es algo injusto creo, porque yo estoy intimamente relacionado con MooTools, por lo tanto leer MooTools es fcil para mi. Pero una de las cosas que aprecio de MooTools es cmo casi todos los mtodos y clases realmente definen lo que son. Los mtodos son casi siempre verbos y dejan muy poca duda sobre lo que hacen. Cada lenguaje de programacin requiere de la lectura de la referencia y de la sintaxis cuando escribes cdigo - No estoy diciendo eso. Yo solo digo que encuentro el API de MooTools ms coherente y consistente.
http://jqueryvsmootools.com/index_es-ar.html
16/07/2010
Page 13 of 26
//entonces tu puedes usarlo exactamente como la versin de jQuery: $$('#orderlist li:last').hover(function(){ this.addClass('green'); }, function(){ this.removeClass('green'); }); De hecho, hay plug-ins de MooTools que justamente hacen eso; ofreciendo la sintaxis de jQuery en MooTools (http://github.com/cheeaun/mooj/tree/master). Que MooTools est enfocado en la extensibilidad significa que puedes implementar lo que quieras. Esto es algo que jQuery no puede hacer. MooTools puede emular jQuery si lo quieres, pero jQuery no puede emular MooTools. Si deseas escribir clases o extender prototipos nativos o hacer alguna de las otras cosas que MooTools puede, lo tendrs que escribir todo t mismo.
http://jqueryvsmootools.com/index_es-ar.html
16/07/2010
Page 14 of 26
faq.getElements('dt').addEvent('click', function() { this.getNext().slide('toggle'); }); }); Nuevamente, el cdigo de MooTools es un poco ms verborrgico, pero tambin, ms explcito. Nota tambin que el patrn de diseo aqu es almacienar la referencia a #faq en una variable, donde jQuery usa el mtodo .end para devolverla. Quiero notar que es posible escribir cdigo con mucho encadenamiento en MooTools. Por ejemplo: item.getElements('input[type=checkbox]') .filter(function(box) { return box.checked != checked; }) .set('checked', checked) .getParent()[(checked) ? 'addClass' : 'removeClass']('check .fireEvent((checked) ? 'check' : 'uncheck'); Pero realmente, escribir codigo como este - un montn de lgica en una sentencia de domready - con cualquier framework, yo sostengo, que en s misma es una mala prctica. Es por lejos mucho mejor encapsular la lgica en partes reutilizables.
http://jqueryvsmootools.com/index_es-ar.html
16/07/2010
Page 15 of 26
$(document).ready(function() { faq('#faq', 'dd', 'dt'); }); Esto es mucho mejor por dos razones realmente grandes e importantes: 1. Si maana necesitamso cambiar como estas listas trabajan (puede ser agregar una lgica de seguimiento de clicks de esa manera podemos medir en nuestros logs o puede que querramos obtener las definiciones via ajax) nosotros solo cambieremos nuestro mtodo principal faq y en cualquier otro lugar donde se use estar actualizado. O tambin si hubiera una nueva versin de jQuery que cambia la forma en que las cosas funcionan, solo actualizamos nuestro nico mtodo en vez de docenas de copias por todos lados. Yo llamo a esto keeping a small footprint in my application. Manteniendo los puntos donde mi aplicacin usa mi cdigo mas genrico tan pequea como sea posible, me hace ms fcil la correccin de errores, actualizar frameworks, agregar prestaciones, o alterar la funcionalidad. 2. La segunda razon es que esti es menos cdigo. Reusando el mismo mtodo una y otra vez, no me repito a mi mismo y esto es valioso en cualquier entorno de programacin. Esto hace tambin que el cdigo que mis visitantes tienen que bajar sea ms pequeo. jQuery actualmente tiene un levemente refinado sistema para escribir "widgets" reusables como estos. En lugar de incitarte a escribirlo en funciones como el ejemplo anterior (que en realidad es bastante crudo) te incita a escribir jQuery plug-ins (http://docs.jquery.com/Plugins/Authoring). As es como esto se vera: jQuery.fn.faq = function(options) { var settings = jQuery.extend({ terms: 'dt', definitions: 'dd' }, options); //"this" is the current context; in this case, the elements $(this).find(settings.terms).hide().end().find(settings.definit $(this).next().slideToggle(); }); return this; }; lo cual lo podemos usar de esta manera: $('#faq').faq();
http://jqueryvsmootools.com/index_es-ar.html
16/07/2010
Page 16 of 26
Pero mirando el ejemplo anterior, no hay mucha diferencia entre declarar nuestra funcin faq de esta manera versus declararla como una funcin simple. Bueno, ella no esta en el namespace global, pero podramos tenerla agregada facilmente a nuestro propio namespace. Asociandola con jQuery nosotros podemos anidarla con otros mtodos jQuery. El otro beneficio es que el "this" dentro de nuestra funcin es el contexto corriente de lo que contiene el anidamiento jQuery en ese momento. Usando este patrn para plug-ins estamos en condiciones de hacer que nuestro plug-in se vea como parte de jQuery, pero por otro lado, nuestro plug-in es basicamente una simple funcin que toma el contexto actual de jQuery, hace cosas con eso, y despus retorna el contexto para el siguiente item en el anidamiento o cadena (chain). No hay un monton de complejidad aqui, lo cual hace sencillo para cualquiera escribir plug-ins de jQuery - ya que son simplemente funciones. Nota que es posible escribir plug-ins ms complejos con jQuery con mtodos y estado. Esta clase de patrn es soportado con el plug-in de jQuery llamado UI system y no usa el mismo mecanismo del plug-in bsico (como nuestro ejemplo de faq). En cambio, puedes anexar un objeto con mtodos y propiedades al objeto jQuery (por ejemplo $.ui.tabs). Hay un acceso directo para invocar este objeto ($(selector).tabs()) de manera que puedes continuar anidando como el plug-in de faq. Pero como este no retorna una referencia al objeto tabs creado para los items en tu selector, te ves forzado a llamar a ese selector nuevamente para llamar a los mtodos que contiene. En vez de llamar myTabInstance.add(url, label, index) debes ejecutar el selector nuevamente y llamar tu funcin por nombre (como string): $(selector).tabs('add', url, label, index);. Esto significa que estas ejecutando tu selector dos veces (al menos que lo almacenes en alguna variable en algn lugar), y que nunca tienes una referencia al mtodo "add" que tu podras facilmente hacer cosas como bind o delay. Este artculo est enfocado en el core de MooTools y jQuery, y mientras UI system de jQuery provee esta funcionalidad, es algo que no viene por defecto.
http://jqueryvsmootools.com/index_es-ar.html
16/07/2010
Page 17 of 26
MooTools; no necesitas agregarlo tu mismo): String.implement({ trim: function() { return this.replace(/^\s+|\s+$/g, ''); } }); Esto significa que simplemente puedes ejecutar " no ms espacios al final! ".trim() y obtener "no ms espacios al final!". Alguien puede decir que implementar propiedades en los objetos nativos es inapropiado. Esta es la razn porque MooTools y Prototype.js (http://www.prototypejs.org/) no se llevan bien juntos - cualquier framework que manipula prototipos de nativos no puede llevarse bien con otro que hace lo mismo. Si yoi defino String.prototype.foo() y otra biblioteca en la misma pgina define lo mismo tambin, la que lo haga ltimo ganar. De modo que, este es un problema similar al de global window namespace. As es como funciona JavaScript. Esto es como a href="https://developer.mozilla.org/En/New_in_JavaScript_1.8">JavaScript 1.8 ha agregado muchas prestaciones. Las agrega a los prototipos. Los programadores de MooTools incluyen un robusto framework que te facilita para extenderlo con tu propia funcionalidad con la intencin de que la gente que incluya el framework en la pagina vaya a usarlo y no use algn otro framework. Actualmente pedir a los usuarios que descarguen dos frameworks sera un poco grosero. La nica razn para incluir dos frameworks es porque deseas usar plug-ins de ambos, y en la mente de los autores de MooTools (me incluyo), si quieres un plug-in que no est disponible en el framework que elejiste, es ms apropiado invertir tiempo portndolo a tu entorno que pedir que descarguen otro framework adicional. Una vez que aprendes como funciona JavaScript y ves el poder de extender los objetos nativos, un nuevo nivel de programacin se abre delante tuyo. Puedes escribir plug-ins que modifiquen Element o Date o Funcion. Mientras algunos pueden decir que agregar mtodos a nativos de esta manera puede ser una clase de polucin. Yo digo que esta es la manera que JavaScript fue pensado para ser usado. Es una cualidad de diseo del lenguaje. Agregando mtodos a nativos te permite tener codigo conciso y compartimentado. jQuery hace esto tambin, pero limita las mejoras de prototipo al objeto jQuery. Mientras puedes anidar facilmente varias llamadas a mtodos en el objeto jQuery, en cualquier otro tipo de objeto tendrs que usar generics. Por ejemplo, en jQuery si quieres hacer trim a un string e iterar sobre cada lnea, deberas escribir:
http://jqueryvsmootools.com/index_es-ar.html
16/07/2010
Page 18 of 26
$.each( $.trim( $('span.something').html() ).split("\n"), function( Pero como MooTools modifica los prototipos, tu puedes hacer esto: $('span.something').get('html').trim().split("\n").each(function(li Hechando una mirada a esto pone extremadamente claro cuan potente es modificar prototipos. La anidacin de elementos del DOM no es el unico lugar donde la anidacin es util. MooTools te permite anidar mtodos a cualquier objeto, incluyendo ejecutar un mtodo en multiples elementos a la vez. La clave aqu es que en el corazn del framework MooTools est la nocin que est ah para permitirte programar lo que quieras. Si hay una funcionalidad que no esta en el core, puedes extenederlo y agregarla tu mismo. El trabajo del core no es proveer todas las funcionalidades que cada uno quiere, sino proveer las herrramientas que te permiten escribir las cosas que desees. Una gran parte de ello es hacer la extensin de nativos ms facil para ti, y obtener ventaja de la herencia prototipada. Puedes hacer estas cosas con JavaScript bsico pero MooTools lo hace ms fcil y placentero.
MooTools y Herencia
A pesar de su nombre, la funcion de MooTools Class no es relamente una clase ni crea ellas. Ella tiene un patrn de diseo que puede hacerte acordar a las clases en un lenguaje de programacin ms tradicional, pero lo que Class realmente hace tiene que ver con objetos y herencia prototipada. (Desafortunadadmente, usando palabras como "class" es lo ms conveniente para describir estas cosas, de modo que para el propsito de ste artculo, cuando me refiera a "classes" me estoy refiriendo a funciones que retornan objetos - los que "instanciar" - que heredan de prototipos.) Para hacer una clase, debes pasarle un objeto al constructor Class de esta manera: var Human = new Class({ initialize: function(name, age) { this.name = name; this.age = age; }, isAlive: true, energy: 1, eat: function() { this.energy = this.energy + 1; //lo mismo que this.energy++ } });
http://jqueryvsmootools.com/index_es-ar.html
16/07/2010
Page 19 of 26
Tu le pasas a Class un objeto (en el ejemplo de arriba, le pasamos un objeto con miembros como "isAlive" y "eat") y este objeto se convierte en el prototipo de cada instancia de esa clase. Para crear una instancia, debes escribirlo de esta manera: var bob = new Human("bob", 20); //el nombre de bob es "bob" y el ti Ahora tenemos una instancia de Human. bob tiene las propiedades de el objeto que definimos cuando nosotros creamos nuestra clase Human. Pero lo importante aqu es que bob tiene las propiedades a travs de la herencia. Cuando referenciamos bob.eat, bob no tiene realmente esta propiedad. JavaScript mira en bob y el no tiene un mtodo eat, por eso busca hacia arriba en la cadena de herencia y lo encuentra en el objeto que le pasamos cuando creamos la clase Human. Esto es vlido tambin para energy. A primera vista esto se ve potencialmente malo; nosotros no queremos que todos los humanos que creemos obtengan energa cada vez que bob come (eats). Lo importante a reconocer es que la primera vez que asignamos un valor a la energa de bob(bob's energy), estamos asignando a su propio valor y no buscamos ms en el prototipo por el. De modo que, la primera vez que llamamos al mtodo eat de bob, el obtiene su propia definicion para energy (seteada en 2). bob.eat(); //bob.energy == 2 Notar que el nombre de bob y la edad son solo de el; estos son asignados a el cuando la clase es inicializada en el mtodo initialize. This whole pattern may seem a little odd to you, but the value here is that we can define functionality for a pattern and create instances of that pattern every time we need it. Each instance maintains its own state. So if we create another instance each one is independent of the other, but inherits from the same base pattern: var Alice = new Human(); //alice.energy == 1 //bob.energy == 2 Donde las cosas se ponen realmente interesantes es cuando queremos fundamentar este comportamiento.
http://jqueryvsmootools.com/index_es-ar.html
16/07/2010
Page 20 of 26
Nuestras unicas opciones reales son, o duplicar la lgica completa del plug-in faq (recuerda que es solo una simple funcin), haciendo un fork escencialmente, o podemos invocarlo y agregarle ms logica a el. Dadas las opciones, la ltima parece traernos menos problemas. Entonces esto debera verse algo as: jQuery.fn.ajaxFaq = function(options) { var settings = jQuery.extend({ //algunas opciones especificas de ajax para obtener la inform url: '/getfaq.php' definitions: 'dd' }, options); //"this" en el contexto actual; en este caso, el elemento q $(this).find(settings.definitions).click(function() { $(this).load(.....); //la lgica que obtiene el contenido }); this.faq(); //la llamada a nuestro plug-in original }); Esto tiene algunas cosas malas. Primero de todo, nuestra clase faq va a repetir nuestro selector para las definiciones, lo cual puede ser costoso; no hay forma de almacenar las definiciones obtenidas y pasarlas por segunda vez donde son requeridas. Secundariamente, no podemos agregar nuestra lgica ajax dentro de la propia lgica plug -in faq para mostrar la definicin que obtuvimos via ajax. El plug-in original llamado slideToggle el cual expande la definicin usando un efecto. Esto es problemtico porque ste efecot va a finalizar antes que nuestro ajax se termine de cargar. No hay una solucin real aqu al menos que dupliquemos completamente el plug-in faq. Consideremos ahora nuestra clase Human en MooTools. Esta tiene propiedades como isAlive y energy y ademas tiene un mtodo llamado eat. Qu psa si queremos hacer una nueva versin de Human que tenga propiedades adicionales? Con MooTools, extendemos la clase: var Ninja = new Class({ Extends: Human, initialize: function(name, age, side) { this.side = side; this.parent(name, age); }, energy: 100, attack: function(target) { this.energy = this.energy - 5; target.isAlive = false;
http://jqueryvsmootools.com/index_es-ar.html
16/07/2010
Page 21 of 26
} }); Puedes ver que hemos agregado un monton de funcionalidad en una subclase. Esta subclase tiene todas las propiedades que son nicas a Ninjas. Ninjas comienza con un valor inicial de energy de 100. Ninjas obtienen un side . Ellos tambin obtienen un mtodo attack que les permite matar a otros Humans, pero esto consume la energa de Ninja. var bob = new Human('Bob', 25); var blackNinja = new Ninja('Nin Tendo', 'unknown', 'evil'); //blackNinja.isAlive = true //blackNinja.name = 'Nin Tendo' blackNinja.attack(bob); //bob never had a chance Alejandonos de esto un momento, hay algunas cosas interesantes a considerar aqu. Nota que tenemos un mtodo initialize en la clase Ninja. Esto podra parecer que sobreescribe el mtodo initialize en la clase Human, pero podemos seguir accediendo al mismo llamando a this.parent, pasando los argunmentos que la clase padre espera en el mtodo initialize. Ms adelante, podemos controlar dnde sucede nuestra lgica; antes o despues de la llamada del mtodo padre (this.parent). Podemos asignar nuevos valores a las propiedades (como el valor de energy) y podemos definir una nueva funcionalidad. Imagina si podriamos hacer esto en nuestro plug-in faq en jQuery. Podriamos cargar nuestra respuesta ajax y ENTONCES mostrar el valor con un efecto slide open. MooTools tiene otro patron llamado Mixin. A diferencia de la relacion padre a hijo que es definida extendiendo una clase en una sublcase, puedes tambin definir clases que son mezcladas en otras clases para imbuir ellas con sus propiedades. Aqui un ejemplo: var Warrior = new Class({ energy: 100, kills: 0, attack: function(target) { target.isAlive = false; this.energy = this.energy - 5; this.kills++; } });
http://jqueryvsmootools.com/index_es-ar.html
16/07/2010
Page 22 of 26
Aqu hemos quebrado las cualidades que hacan a un Ninja diferente de un Human y pusimos esto en una clase. Esto nos permite reusar el codigo fuera de Ninja. Podramos entonces imbuir nuestra clase Ninja con las cualidades de warrior as: var Ninja = new Class({ Extends: Human, Implements: Warrior, //puede ser un array si deseas implementar initialize: function(name, age, side) { this.side = side; this.parent(name, age); } }); Ninja continua funcionando como lo hice anteriormente, pero Warrior esta a nuestra disposicin para ser reusado: var Samurai = new Class({ Extends: Human, Implements: Warrior, side: 'good' }); Ahora tenemos una clase Samurai y una clase Ninja. Pero miremos cuan pequeo es el codigo para definir ambas clases Ninja y Samurai. Ambas son similares en que son humanos con cualidades de warrior, pero ellas son diferentes en que samurais son siempre, siempre buenos (good), mientras que los ninjas pueden cambiar sus lealtades. Invirtiendo el tiempo en escribir la clase Human y la clase Warrior, estaremos en condiciones de tener tres clases diferentes con ninguna repeticin de codigo mientras mantiene un nivel de control muy granular sobre los mtodos cuando son llamados y cmo se relacionan uno con otro. Cada instancia que creamos tiene su propio estado y el cdigo en s es muy legible. Ahora que tienes un panorama de como las clases funcionan en MooTools, echmosle una mirada a nuestra clase faq que escribimos en jQuery y escribmosla en MooTools y luego extendmosla a Ajax como lo hicimos con jQuery. var FAQ = new Class({ //Options es otra clase provista por MooTools Implements: Options, //these are the default options options: { terms: 'dt',
http://jqueryvsmootools.com/index_es-ar.html
16/07/2010
Page 23 of 26
definitions: 'dd' }, initialize: function(container, options) { //guardamos una referencia a nuestro contenedor this.container = $(container); //setOptions es un mtodo provisto por el mixin Opt //ste une (merge) las opciones que le pasamos con this.setOptions(options); //almacenamos los trminos y definiciones this.terms = this.container.getElements(this.option this.definitions = this.container.getElements(this. //llamamos a nuestro mtodo attach //separando esto en su propio mtodo //hace nuestra clase ms fcil de extender this.attach(); }, attach: function(){ //iteramos por los trminos this.terms.each(function(term, index) { //agregamos el evento Click a cada uno term.addEvent('click', function(){ //esto llama a nuestro mtodo toggl //el index actual this.toggle(index); }, this); }, this); }, toggle: function(index){ //invierte la definicion abierta por la recibida en this.definitions[index].slide('toggle'); } }); Woah (Necesito un traductor especial para esta palabra ;-) ). Esto es un montn de cdigo. As y todo si elimino las lneas de comentarios quedan como dos docenas de lneas de cdigo. Ya he ilustrado anteriormente que podramos hacer este plug-in con la misma cantidad de cdigo como la versin de jQuery. Entonces porqu ste es tanto mas largo? Bien, lo hemos hecho mucho ms flexible. Para usasr la clase, simplemente llamamos el constructor, as:
http://jqueryvsmootools.com/index_es-ar.html
16/07/2010
Page 24 of 26
var myFAQ = new FAQ(myContainer); //y ahora podemos llamar los mtodos que contiene cuando querramos: myFAQ.toggle(2); //invierte el 3er elemento Podemos acceder a los mtodos y propiedades de la instancia. Pero que pasa con nuestra funcionalidad ajax? El problema con nuestra extensin ajax en nuestra versin jQuery era que no podamos frenar la apertura de la definicin hasta despues de la carga de la misma. No tenemos ese problema con nuestra versin de MooTools: FAQ.Ajax({ //esta clase hereda las propiedades de FAQ Extends: FAQ, //esta tambin obtiene una nueva opcin sumada a las por de //esta es para la url, lo que vamos a agregar al indice del trmi //en realidad podemos hacer esto ms robusto, pero para //este ejemplo es suficiente options: { url: null; }, //vamos a hacer caching de los resultados, de mode que si u //abierta dos veces, no iremos al servidor por los datos nu indexesLoaded: [], toggle: function(index){ //si ya hemos ledo la definicion if (this.indexesLoaded[index]) { //solo llamamso la version previa de toggle this.parent(index); } else { //cualquier otro caso, obtenemos los datos new Request.HTML({ update: this.definitions[index], url: this.options.url + index, //cuando los datos estan cargados, onComplete: function(){ this.indexesLoaded[index] = this.definitions[index].sli }.bind(this) }).send(); } } });
http://jqueryvsmootools.com/index_es-ar.html
16/07/2010
Page 25 of 26
Ahora tenemos una versin de nuestra clase FAQ que nos permite obtener definiciones desde el servidor. Notar que ahora estamos en condiciones de integrar la nueva manera de no expandir la definicion hasta despus que el contenido lleg del server (lo cual no hemos podido realizar con la versin de jQuery). Tambin nota que nosotros realmente tenemos solamente que describir nueva funcionalidad (la ajax) y un poquito ms. Esta extensibilidad hace te hace posible crear familias de plug-ins que ofrecen diferentes estilos de funcionalidades. Esto tambin significa que puedes usar el plug-in de alguien ms y modificar solo el comportamiento que quieres que sea diferente si necesitas (sin realizar un fork). Esto ayuda a explicar porqu, para cualquier patron de diseo dado - un selector de fecha, una interfase con tabs, etc, que normalmente encuentras solo unos pocos plug-ins para MooTools. La mayora de los plug-ins que obtienes o solucionan tu problema o, si no, simplemente puedes extenderlos para agregar las cosas que necesitas. Como he ilustrado anteriormente, es posible escribir cdigo complejo con widtets de jQuery con mtodos y estados. La mayora del codigo que escribes cuando estas haciendo esto es JavaScript bsico cuando necesitas expresar lgica que no est relacionada al DOM. Pero el modelo jQuery no ofrece un sistema para extender estas instancias en subclases. Ni tampoco te ayuda con mixins que pueden ser reusados fcilmente. Finalmente, los plug-ins de jQuery estn siempre asociados a elementos DOM. Si quieres escribir una clase que, devuelva, URLs procesadas, no hay ningun sistema stateful para ese tipo de cosas excepto que lo escribas tu mismo.
Tiempo de decisin
jQuery se enfoca en expresividad, codificacin fcil y rpido, y en el DOM mientras MooTools se enfoca en extensin, herencia, legibilidad, reuso, y mantenibilidad. Si tu pones estas dos cosas en la balanza, el lado de jQuery se traduce en algo que es fcil para empezar y se ven rpido los resultados pero (en mi experiencia) se puede convertir en cdigo ms dificil de mantener o reusar (pero realmente eso est de tu lado, no es un problema de jQuery), mientras el lado de MooTools toma ms tiempo para aprender y requiere que escribas ms cdigo antes que puedas ver los resultados, pero luego es ms reusable y mantenible. El core de MooTools no contiene cada prestacione que puedes imaginar ni tampoco lo hace el core de jQuery. Ambos frameworks mantienen sus cores bastante limitados, dejandote a vos y a otros escribir plug-ins y extensiones. Su trabajo no es darte cada prestacin que podras querer sino darte las herramientas para que puedas implementar cualquier cosa que puedas imaginar. Este es el poder de JavaScript, y de los frameworks de JavaScript en general, y ambos frameworks sobresalen en esto. MooTools toma un acercamiento ms holstico y te da un superset de las prestaciones de jQuery, pero jQuery
http://jqueryvsmootools.com/index_es-ar.html
16/07/2010
Page 26 of 26
se enfoca en ser una rpida API del DOM que no evita que uses la herencia nativa de los mtodos de JavaScript o de usar un sistema de clases como MooTools si lo deseas. Esto es porqe yo digo que ambos frameworks son excelentes opciones. Mi esfuerzo aqu ha sido resaltar las diferencias de filosofas entre las dos lineas de codificacin y resaltar sus ventajas y desventajas. Dudo que haya tenido xito en mantener mi preferencia por MooTools en jaque, pero ojal esto haya ayudado. Sin hablar de que framework elijas para trabajar, ahora sabes mucho ms de ambos, al menos eso espero. Si tienes el lujo de tener tiempo, te recomiendo seriamente implementar un sitio con cada uno. Entonces escribes tu propia experiencia de ellos dos y probablemente tu perspectiva resalte algunas cosas que a mi se me han pasado. La historia del documento puedes verla en github
(http://github.com/anutron/jquery-vs-mootools/tree/master).
ShareThis (javascript:void(0))
About me: I am a MooTools (http://www.mootools.net) contributor and I blog about JavaScript and other things on my site Clientcide (http://www.clientcide.com) as well as release numerous plug-ins for MooTools (http://www.clientcide.com/js). I am the author of MooTools Essentials
(http://www.amazon.com/gp/product/1430209836?ie=UTF8&tag=clientside20&link_code=as3&camp=211189&creative=373489&creativeASIN=1430209836) as well as the MooTools online
tutorial (http://www.mootorial.com). I work at a company in the SF Bay Area called Cloudera (http://www.cloudera.com). I can be contacted thusly (http://www.clientcide.com/shout-out).
Una nota sobre comentarios aqu: Estos comentarios son moderados. Los comentarios no se mostraran hasta que no sean aprobados. Comentarios que no son productivos (ej. mal educados, insultos, o
http://jqueryvsmootools.com/index_es-ar.html
16/07/2010