Continuum

Continuum

Continuum Chile: Agilistas y Desarrolladores Web en Java, Ruby, Rails ..Java, Python, Ruby, Javascript, Ajax, Web 2.0, ESB, SOA…
Continuum

Prototypejs y OO clásico en Javascript.

En javascript la herencia es de tipo prototipo, todos los objetos heredan de Object una propiedad llamada .prototype que es la referencia hacia el super-objeto donde buscar en caso de no encontrar un método o una propiedad en el objeto actual.

La librería «prototypejs» fue un poco más allá y le agregó a javascript sintaxis para simular herencia clásica, donde puedes definir clases con constructores, propiedades y métodos comunes a sus instancias, y heredar de estas usando una forma que si bien no se parece a ningún lenguaje que conozca simula la orientación a objetos clásica de lenguajes como Java, Ruby o Python, aunque de estos es a Ruby al que más se me parece por el método constructor “initialize”.

Yo lo he estado usando en un proyecto personal. Aquí va un fragmento de código que muestra como se usa el Class.create para generar los modelos de clases:

    model.actions.Action = Class.create({
        initialize: function(_object) {
          this.id = _object.id;
          this.target = _object.target;
          this.start_time = _object.start_time || 0;
          this.end_time = _object.end_time || 0.1;
          this.range = _object.range || true;
        },
        to_json: function() {
          return Object.toJSON(this);
        },
        render_to: function(element) {
          ...
          if (this.render_action && typeof this.render_action == 'function') {
            ...
          }
          ...
        },
    });

    model.actions.Walk = Class.create(model.actions.Action, {
      initialize: function($super, _object) {
        $super(_object);
        this.steps = _object.steps || 1;
        this.name = "walks";
        this.class_name = "Walk";
      },
      load_from_obj: function($super, _object) {
        return new model.actions.Walk(_object)
      },
      render_function: function() {
          ...
      },
      display: function() {
        return this.target + " " + this.name + " " + this.steps + " steps";
      }
    });

Luego es posible crear instancias que responden a estos modelos y permiten usar polimorfismo o delegación en forma natural, sin tener que preocuparnos por usar la propiedad .prototype o constructores de tipo función para simular estos comportamientos, por ejemplo:

      var w = new model.actions.Walk({
          id: "uyu121uyi1287312",
          target: "Panfilo",
          start_time: 0,
          end_time: 7.2,
          steps: 3
      })
      w.render_to(_$('#dv-actions-content'));

Nota: Para los que usan jQuery, hay conflictos entre ambas librerías por el uso del alias $, la solución es usar el método jQuery.noConflict() que libera el alias $ para su uso por cualquier otra librería. Otro detalle es que prototypejs debe ser cargado antes que jQuery en el body del HTML.

Video: El estado y el futuro de Javascript [Douglas Crockford]

El arquitecto JavaScript de Yahoo Douglas Crockford discute los recientes procesos y esfuerzos de ECMA5 para mejorar el lenguaje en el futuro no distante.

Respuesta a: “Cual es la forma más breve ? [1]“

Ok, lo prometido es deuda, aquí esta la respuesta correcta a Cual es la forma más breve [1] (Fue enviada por Leo Soto a info arroba continuum punto cl)

return x && x.validate() && “x es valido” || “x no es valido”

Justificación:

JavaScript retorna siempre la última evaluación de una expresión que sea verdadera, por ejemplo  “return x” retorna la referencia del objeto “x” si es que “x” apunta a algún lado, de lo contrario retorna false. (Observación: “x” debe haber sido declarada anteriormente, de lo contrario debe usarse “typeof x” que retorna false si x no existe (es null) ).

Por otro lado, si cualquier variable o retorno de método es diferente de 0, undefined o null en una expresión condicional esta es evaluada como verdadero (true).

De ahi que si x no es undefined y además x.validate() es verdadero y “x es valido” (evalua en un objeto String literal), se retorne “x es valido”, pues fue la última expresión verdadera. Si lo anterior resultara en false, entonces el circuito evalua lo que hay despues del OR ( “||” ), que en este caso es “x no es valido” (que de nuevo es un objeto String en notación literal) y como no es null o undefined entonces es verdadero y se retorna el objeto.

Genial no?, al principio parece desconcertante pero al comenzar a escribir código aprovechando características como esta se reduce mucho la cantidad de lineas y el código luce más limpio y fácil de mantener.

Incluso puede hacerse más fácil de leer colocando parentesis para separar el circuito:

return (x && x.validate() && “x es valido”) || “x no es valido”

« Entradas Anteriores Entradas Siguientes »

 
Copyright © 2012 Continuum Ltda. Coronel Pereira 72. Oficina 903. Las Condes. Santiago. Chile
Tel: +56 2 9341951