OOP en Javascript

29 Jun 2009, (Comentarios)

Javascript

Javascript debe ser el lenguaje mas malentendido del mundo, pero resulta ser uno de los lenguajes mas interesantes y poderosos que hay, con sus bases funcionales se pueden hacer cosas muy interesantes y una de ellas es la programación orientada a objetos, aun que, sorprendentemente, esto es algo que no muchos saben que se puede hacer y mi intención es darle un par de vueltas en este post.

La gente que ha jugado con javascript estará acostumbrada a código eminentemente procedural con código como el siguiente:

function function_name(param1, param2, param3) {
  // Do something!
}

function_name(some, actual, params);

Está bien, se hace lo que se pide pero, imaginen unas 20, 30 o mas funciones de esas y ya tienes una pesadilla.

Luego uno conoce JSON que es excelente para pasar parámetros o transferirlo por la red.

some_function({
  arg1: 'value1',
  arg2: 'value2'
});

Esto definitivamente hace mas facil entender que se está haciendo, pero todavía falta algo, esas funciones desperdigadas por el mundo me molestan, así que definamos “objetos de verdad” ahora!

function Person(name) {
  this.name = name;
}

Person.prototype.greet = function() {
  alert('Hello, ' + this.name);
}

// Y lo usamos:
var p = new Person('Sebastián');
p.greet();

Aquí creo que debería aclarar que es Person.prototype, el modelo de objetos de JavaScript se basa en en prototipos y el objeto Person.prototype no es mas que una colección de propiedades que se ván a copiar en toda instancia de Person que se cree, de hecho, nos podemos aprovechar de esto para implementar herencia!

function Employee(name, company) {
  this.name = name;
  this.company = company;
}

Employee.prototype = new Person();

var e = new Employee('Sebastián', 'Gaaper');
e.greet();

Esto sorprendentemente comienza a verse mejor y se vuelve mucho mas interesante cuando se entienden correctamente las clausuras (que para los que vienen de Ruby notarán que se parecen mucho a los bloques pero un poco mas potentes) ya que usándolas inteligentemente se pueden implementar encapsulamiento y espacios de nombres.

Veamos una clausura básica:

(function() {
  var private = 0;
  
  window.increaseValue = function() {
    private++;
  }
  
  window.getValue = function() {
    return private;
  }
})();

getValue();       // retorna 0;
increaseValue();
private--;        // error: ReferenceError: Can't find variable: private
getValue();       // retorna 1;

Esto básicamente encapsula el valor de private que es inaccesible desde fuera de la clausura y define las funciones increaseValue y getValue que permiten acceder y modificar private. Y para esto solo hizo falta definir una función anonima y ejecutarla!

Pero nos falta una cosa todavía, estas funciones están definidas en window por lo que se corre el riesgo de que existan conflictos de nombre con otro script y para eso acuden los espacios de nombres al rescate!

Namespace = {};

(function($) {
  var private = 0;
  
  $.increaseValue = function() {
    private++;
  }
  
  $.getValue = function() {
    return private;
  }
})(Namespace);

Namespace.increaseValue();
Namespace.getValue();

Fácil y rápido, hemos cambiado el ejemplo anterior para que utilizara un Espacio de Nombre y no definiera los métodos en window.

La verdad es que JavaScript es un lenguaje muy dinamico y existen otras formas de hacer todo lo que puse aquí cada una con sus pros y contras, pero intenté mantener todo lo mas sencillo posible y utilizando los diseños que a mi me parecen mas elegantes y si tienen alguna idea de como esto se podría hacer mejor, me encantaría que la plantearan en los comentarios.

Para finalizar les dejo un ejemplo que aplica gran parte de lo que puse aquí, es un poco mas complejo pero adelante ;)

(function($) {
  // Aquí defino la "clase Foo"
  function Foo(text) {
    /* Variable de instancia pública */
    this.text = text || privateMethod();
    
    /* Variable de instancia privada */
    var priv = 'ehem';
    
    /* método público que utiliza la variable privada */
    this.setPrivate = function(p) { priv = p; }
    
    /* método privado */
    function privateMethod() { return 'this is private: '+priv; }
  }
  
  Foo.prototype.getText = function() { return this.text; }  
  
  /* Variable de clase privada */
  var class_priv = 0;
  
  /* Método de clase público */
  Foo.bar = function() { 
    class_priv++; 
    return new Foo('bar'+class_priv); 
  }
  
  /* Método de clase privado */
  function helloFoo() { return new Foo('Hello'); }
  
  $.Foo = Foo;
  
})(window);

var f = new Foo('Hello!');

Y si quedaron con gusto a poco, aquí les dejo un lugar donde encontrar mas información pero en inglés.

Fácil y rápido

28 Jun 2009, (Comentarios)

Así es otra vez estoy inaugurando un nuevo sitio personal, pero esta ves utilizando las herramientas con las que en verdad me siento cómodo, ¡mi editor y mi terminal!

Ya lo se, es tan facil tener un sitio ahora. Instala Wordpress y listo!, pero para mí usar Wordpress es como usar Word, sencillamente complicado, me saca de mi flujo normal de trabajo y todas esas ventajas no se vuelven mas que distracciones y luego de ver lo que ofrecen los chicos de GitHub, pensé “Eso es justo lo que necesito!”.

La idea es fácil:

  • Te creas un repositorio llamado tu-nombre.github.com (donde tu-nombre es tu usuario en GitHub)
  • haces el sítio (casi como si fuera contenido estático)
  • lo subes, usando git, al repositorio que acabas de crear
  • y ya está, GitHub hace el resto.

Y siempre lo pueden complicar mas si quieren, de hecho es bastante personalizable y pueden aprender mas aquí.

Por cierto todo el sitio lo pueden encontrar en el repositorio sagmor.github.com

No soy delincuente

02 Apr 2009, (Comentarios)

Simplemente genial, porque todos somos delincuentes!? por Jani Dueñas

Vía: Huasonic | Más información en Nosoydelincuente.cl

Liberando Feeling Needish

30 Mar 2009, (Comentarios)

Saludos, hace tiempo que no escribo nada por acá.

Así que vamos, para variar, a colocar algo que le puede interesar a aquellos que están metidos en lo que es el desarrollo de aplicaciones nativas para el iPhone, se trata de la primera aplicación que desarrollé, bien fea por cierto, pero que mas se le puede pedir a un humilde ingeniero con un mes de trabajo ;)

Se trata de la aplicación con la que participé en el concurso Web2.0Rockstars en la que accedo a la api de Needish y pueden encontrar su código fuente completo aquí!.

Ojalá a alguien le sirva y le saque provecho…

Código Fuente CelShader

17 Nov 2008, (Comentarios)

Luego de haber trabajado limpiando un poco el código de la aplicación, y aprovechando que Apple levantó el NDA del iPhone, es un agrado informarles que el código fuente se encuentra disponible en mi repositorio Git en:

http://github.com/SagMor/iphone-celshader/

Posts anteriores:

Versión final del proyecto de Cel-Shading 16 Nov 2008 (Comentarios)
Cel-Shading Funcionando 19 Oct 2008 (Comentarios)
Soy un Desarrollador Certificado! 25 Sep 2008 (Comentarios)
Carga de Modelos 3D 20 Sep 2008 (Comentarios)
Definida la plataforma 18 Aug 2008 (Comentarios)
Inicio del proyecto de Computación Gráfica 09 Aug 2008 (Comentarios)