Clases 01

Introducción

Vamos a estudiar como implementar clases con javascript y MooTools. Esta será una labor trabada, lenta y engañosa; sobre todo para aquellos (como yo) que no dominamos este lenguaje y estamos acostumbrados a otra sintaxis, por ejemplo PHP.

JavaScript en general es un lenguaje rarito, y en particular a la forma de implementar objetos. Digamos que es el nene mañoso mal aprendido de la familia, y que parece que no va a cambiar.

Técnicamente, un objeto de JavaScript es un array asociativo formado por las propiedades y los métodos del objeto. (Introducción a AJAX).

Tenemos que tener claro el modo de declaración de JS, tanto para variables, arrays, funciones, etc. Este es el punto crucial para no marearnos entre paréntesis, llaves y corchetes. Vamos a empezar de atrás para adelante. Partimos de una definición de clase con MooTools e iremos desmenuzando su complejidad; sería algo así como ingeniería inversa.

Estructura de una clase

El paradigma de programación orientado a objetos es tan extenso que su comprensión nos puede superar ampliamente; más si lo queremos resolver en 10 renglones.
Frente a este condición por lo pronto lo que haremos es aclarar conceptos básicos y principales siempre pensando en JS y MooTools. No olvidemos MooTools is a compact, modular, Object-Oriented JavaScript framework. Dejamos entonces POO en Wikipedia para afirmar y refrescar los conceptos básicos.

Clase y Objeto

Las clases contienen funciones dentro de la misma manera que pueden contener variables. (como this.options) (Classes en Clientside).

Por definición, que se desprende de la naturaleza conceptual innata de lo que es una clase / un objeto, a las variables de clase se las denominan propiedades, y a sus funciones, métodos. Avanzando un poquito más, las propiedades serían algo así como las características del objeto (color, olor, peso, edad, ...) mientras que sus métodos serían las acciones que este puede realizar (dormir, comer, caminar, correr, ...). Las propiedades: adjetivos, las métodos: verbos.

Nuestra primer clase con MooTools.

Como programadores podemos crear una clase para luego, a partir de esta, crear un objeto. Se dice que al crear un objeto se instancia una clase.
Copiamos la definición de esta clase realizada en MooTools que se presenta en la doc oficial; nos tomamos la libertad de traducir los comentarios.

var Animal = new Class({
    initialize: function(options) {
        this.options = options;  // Guardamos nuestras opciones

        /* Si las opciones especifican que ...
        * ... al crear el animal esta asleep (dormido) ...
        * ... llamamos al método sleep () (dormido) */

        if(this.options.sleepOnStart) this.sleep();

        // Si no lo está ... está awake (despierto)
        else this.awake();
    },

    sleep: function() {
        this.isAsleep = true;
    },

    awake: function(){
        this.isAsleep = false;
    }
});

Definición de clase Animal.

Seguimos aclarando: La palabra Class no está reservada en javaScript. La definición de la clase Class es propia de MooTools (y de otros frameworks); sin embargo, ya esta pre-establecido que en próximas versiones de JS contendrá dicha definición.

Bien. Tenemos una clase definida en la variable Animal. Esta clase tiene propiedades, definidas dentro de options, y tres métodos: initialize, sleep y awake.
Vamos por partes:

Con esta clase, así como está, no nos sirve de mucho. Es como tener una cafetera sin tener una tasita con café.
La clase es nuestra herramienta para crear un objeto; entonces, creemos uno:

var Cat = new Animal ({
    color: "black",
    sleepOnStart: true
    });

//kitty está dormido, vamos a despertarlo !
Cat.awake();
alert('Kitty color ' + Cat.options.color + ', esta dormido ? - ' + Cat.isAsleep);

Creamos objeto Kitty.

Desmenucemos

Las Propiedades

Una de las cosas que más me ha confundido es como se asignan las opciones color y sleepOnStart. Partamos del hecho que efectivamente estas propiedades ya son parte del objeto. La pregunta es ... como ?
Observemos estas dos líneas:

initialize: function(options) {
    this.options = options;  // Guardamos nuestras opciones

Pues bien, es bastante sencillo:

Primero: En la definición de clase hemos definido la propiedad options (this.options) y le hemos asignado el valor pasado como parámetro del constructor. La palabra tan sonada this se utiliza para referenciar al objeto en cuestión sin saber su nombre. A ver ...

cuando yo escribo ...
- this.color = 'red'
... estoy diciendo
- ponele color rojo al objeto, no se cual es su nombre ni me interesa !!!.
Se entiende ?. Espero que si ...

Segundo: Al crear el objeto hemos asignado las propiedades color y sleepOnStart ... pero en ningún momento las hemos predefino. Generalmente cuando uno diseña una clase, las propiedades suelen estar definidas en su declaración; cuestión que al crear el objeto a partir de esa clase uno no podría salirse de su estructura.
Lo vuelvo a decir, JavaScript es particular. Y este comportamiento que en primera instancia nos desubica puede ser claramente entendido conociendo los Arrays en javaScript; conste que lo aclaré desde un principio.

Básicamente lo que estamos haciendo es pasándole como valor a la clase (options) un array asociativo de dos elementos. Al crear el objeto pasamos como parámetro:

{
    color: "black",
    sleepOnStart: true
    }

Esto es un Array definido con la notación JSON (que se pronuncia algo así como Yeison). Sus siglas abrevian JavaScript Object Notation. JSON es otro piojo resucitado gracias a su primo mayor AJAX.
Otro tema más que interesante que no abordaremos ahora. Sólo diremos que podemos definir un array con esta notación y que resulta mucho mas sencillo que con las tradicionales.

Nada mejor que un ejemplo donde definimos el mismo array de tres maneras distintas.

// Notacion clasica
    pseudoTutor['nombre'] = 'Damian';
    pseudoTutor['edad'] = 30;
    pseudoTutor['sexoMasculino'] = true;

// Notacion de array.elemento (tipo OO)
    pseudoTutor.nombre = 'Damian';
    pseudoTutor.edad = 30;
    pseudoTutor.sexoMasculino = true;

// Notacion JSON
    pseudoTutor = {
        'nombre': 'Damian',
        'edad': 30,
        'sexMasculino': true
    };

Como quedaría entonces el array options con las notaciones clásicas, sólo para entender la sintaxis un poco más ?
La más común es la clásica de corchetes, esa que se usa desde QBasic o el Pascal de Borland:

// Definimos opciones en un array externo:
    myOptions ['color'] = "black";
    myOptions ['sleepOnStart'] = true;

Y finalmente queda la última notación que es muy parecida a la forma de acceso a las propiedades y métodos de un objeto en otro lenguajes. Es la que tiene la forma objeto.propiedad y/o objeto.método.

// Definimos opciones en un array externo:
    myOptions.color = "black";
    myOptions.sleepOnStart = true;

Y los métodos ... ?

Pues bien, si prestamos atención a la declaración de la clase en su totalidad esta es un array definido en notación JSON, donde el primer elemento es una variable de nombre initialize ... pero esta variable es una función ???. Si amigo, es una función, lo mismo sucede con los elementos sleep() y awake().

Funciones Anónimas

Las funciones también se pueden crear mediante lo que se conoce como "functions literals" y que consiste en definir la función mediante una expresión y en la que el nombre de la función es opcional. Debido a esta última característica, también se conocen como funciones anónimas (Introducción a AJAX)

Por ejemplo, podríamos definir la función initialize de la siguiente manera:

var initialize = function (options) {
    this.options = options;  // Guardamos nuestras opciones

    /* Si las opciones especifican que ...
    ... al crear el animal esta asleep (dormido) ...
    ... llamamos al método sleep () (dormido) */

    if(this.options.sleepOnStart) this.sleep();

    // Si no lo está ... está awake (despierto)
    else this.awake();
};

... pero si usamos JSON para definirla como un elementos más del array principal, nos queda de la forma ...

'initialize': function (options) { ...}

O sea, la misma cosa con distinto olor.

Finalizando

Arrays dento de Arrays, funciones que son variables, que son elementos de un array, etc. A eso me refiero a que javaScript es un lenguaje particular.

Nada nos impide declarar clases pensándolo como arrays y utilizar la notación clásica; pero sucede que es más enredado y no se justifica. Justamente una de las causas de la existencia de JSON es simplificarnos la vida. Entonces, para que la vas a complicar ?. Que jodido que sos !

Ahora, de que sirve toda esta explicación y las comparaciones ?. Es una buena forma de entender el comportamiento tanto al momento de diseñar una clase como al momento de instanciar un objeto. Por ejemplo, como es el ámbito de una variable dentro de un objeto ?. Tal vez si pensaras que en realidad se trata de un elemento de un array podrías analizarlo mejor.

En fin, queda mucha tela por cortar. MooTools se aprovecha de esta aparente ambigüedad de javaScript e implementa funcionalidades propias de la programación orientada a objetos, como por ejemplo herencia de clases. Y es por esto también que tenemos que tener sumamente clara la sintaxis ya que es la que se utiliza prácticamente todo el tiempo cuando uno programa con MooTools.

Este capítulo no ha sido muy constructivo en forma práctica; pero hemos de alguna manera aplanado el terreno. Hasta en cualquier momento ...

3 Comments »

  1. Cabeza de Ratón » Clases con JavaScript && MooTools dice,

    November 19, 2007 at 11:39

    […] Empecemos entonces … […]

  2. eduardo dice,

    November 22, 2007 at 5:31

    Muy buena explicación, se entiende bien para aquellos como yo que no usamos javascript y si php :D un saludo y sigue con mas tutoriales de estos.

  3. RetroFOX dice,

    November 23, 2007 at 8:43

    Esa es la idea. Que bueno que te sirva. Voy a tratar de seguir con este tema.
    Saludos.

Comentarios