Simular clases en Javascript

A diferencia de otros lenguajes de programación como Java, PHP o C#; en javascript no existe el concepto de clases. Osea para el que no sepa, una clase nos sirve de molde para crear objetos. Entonces aunque no podamos crear clases de forma nativa (existen librerías que nos permiten esto), tampoco es un impedimento para diseñar objetos.

Objetos

Aunque no voy a profundizar en esto, ya que no me alcanzaría una sola publicación, y teniendo en cuenta que existen libros enteros hablando de programación orientada a objetos; un objeto nos permite trabajar con información más bien compleja. Por ejemplo, si necesitáramos guardar el nombre de un perro, podríamos crear una variable de tipo string, con este valor. Sin embargo si necesitáramos guardar toda la información de este perro, no sólo su nombre, sino también: peso, color, raza, año de nacimiento, etc; tendríamos que crear un objeto, el cuál estaría compuesto por propiedades (datos del objeto), en donde cada una de éstas serviría para guardar la información del perro.

JSON

Es la forma más utilizada de representar objetos en Javascript, por su simplicidad y además porque en las peticiones ajax, el servidor puede devolvernos información con este formato.

Por ejemplo:

var lamparita = {color: 'Blanca', encendida: true,};

Como vemos este objeto tiene dos parámetros, color y encendida. Si quisiéramos acceder a las propiedades, por ejemplo color, deberíamos hacer:

lamparita.color

Otro ejemplo más profundo:

console.log('La lamparita es de color: ' + lamparita.color);
if(lamparita.encendida){ 
   console.log('Está encendida') 
}else{ 
   console.log('Está apagada');
}

También podríamos crear una lista de lamparitas en donde cada posición será un json con los datos:

var lamparitas = [ 
   {color: 'azul', encendida: true},
   {color: 'blanca', encendida: false},
   {color: 'roja', encendida: true}
];

De función a objeto

Una particularidad de Javascript es que una función nos permite instanciar un objeto, como si se tratara de una clase. Por ejemplo:

function Lampara(){}

Esto nos permite crear objetos, con la palabra reservada new, como esto:

var lampara = new Lampara();

Sin embargo, nos estaría faltando agregarle propiedades. Para ello usamos la palabra reservada this:

function Lampara(p_color, p_encendida){
   this.color = p_color;
   this.encendida = p_encendida;
}

Al ser una función, podemos pasar parámetros cuando creamos una instancia:

var lamp1 = new Lampara('Azul', true);
var lamp2 = new Lampara('Roja', true);
console.log('Lampara 1 es de color: ' + lamp1.color);
console.log('Lampara 2 es de color: ' + lamp2.color);

Al tratarse de objetos también podemos agregarle métodos:

function Lampara(p_color, p_encendida){
 this.color = p_color;
 this.encendida = p_encendida;
 this.mostrarInformacion = function(){
    console.log('Lampara es de color: ' + this.color);
    if(this.encendida){
       console.log('Está encendida');
    }else{
       console.log('Está apagada');
    } 
    console.log('--------------------------') 
 };
} 
var lamp1 = new Lampara('Azul', true);
var lamp2 = new Lampara('Roja', true); 
lamp1.mostrarInformacion(); 
lamp2.mostrarInformacion();

Propiedad prototype

Otra forma de agregar métodos es mediante la propiedad prototype. Por ejemplo:

var Cuadrado = function(p_medida_por_lado){
   this.medida_por_lado = p_medida_por_lado; 
};
Cuadrado.prototype.getPerimetro = function(){
   return this.medida_por_lado * 4; 
};
Cuadrado.prototype.getArea = function(){ 
   return Math.pow(this.medida_por_lado, 2); 
}

Como podemos ver, primero podemos crear una entidad Cuadrado, a la cual debemos pasar como parámetro la medida de sus lados. Luego mediante prototype, agregamos dos métodos getPerimetro()getArea():

var cuadrado = new Cuadrado(15);
console.log(cuadrado.getPerimetro());
console.log(cuadrado.getArea());

Ejemplo final

En mi caso en particular yo hago una combinación de ambas formas, creando una función y retornando en ella un json, donde defino las propiedades y métodos que podrán ser accedidos en el objeto:

var Caballo = function(p_numero, p_nombre){
  return {
     numero: p_numero,
     nombre: p_nombre, 
     tiempo_en_llegar: Math.floor((Math.random() * 60000) + 1000),
     correr: function(callback_meta){ 
        var that = this;
        setTimeout(function(){ 
           callback_meta(that); 
        }, that.tiempo_en_llegar); 
     } 
  };
};

En este caso tenemos un objeto Caballo, el cual tendrá dos propiedades: numero y nombre que se pasan como parámetro al crear el objeto, y una tercera tiempo_en_llegar con la cantidad de tiempo en milisegundos que va a tardar el caballo en llegar a la meta. Esta última propiedad va generarse al azar.

También un método correr() el cual va a simular el tiempo que tarda un caballo en llegar a la meta. Vamos a pasar como parámetro un callback, osea una función que va a ejecutarse una vez que el caballo llegue a la meta.

Finalmente podemos hacer una prueba, creando varios objeto Caballo, y simulando una carrera:

var caballos = [
  new Caballo(1, 'Ezio'),
  new Caballo(2, 'Bayek'),
  new Caballo(3, 'Altair'),
  new Caballo(4, 'Edward'),
  new Caballo(5, 'Connor'),
  new Caballo(7, 'Jacob'),
  new Caballo(8, 'Arno')  
];
for(var i = 0; i < caballos.length; i++){
   caballos[i].correr(function(caballo){
      console.log(caballo.numero + ' - ' + caballo.nombre + ' llega a la meta. ' + (caballo.tiempo_en_llegar / 1000) + ' segundos.'); 
   });
}

En mi caso el resultado será:

5 - Connor llega a la meta. 18.9 segundos.
8 - Arno llega a la meta. 31.765 segundos.
1 - Ezio llega a la meta. 44.092 segundos.
7 - Jacob llega a la meta. 48.304 segundos.
2 - Bayek llega a la meta. 48.709 segundos.
3 - Altair llega a la meta. 55.494 segundos.
4 - Edward llega a la meta. 60.381 segundos.

 

 


Deja un comentario

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *