JavaScript 00: 5. Algunos casos prácticos

Diferentes maneras de definir objetos en javaScript

Waterhouse

archivado en: JavaScript / 25 diciembre, 2014 / taller:

Como hemos visto en esta serie sobre javaScript orientado a objetos existen muchas maneras de declarar objetos y esto es algo que a veces descoloca un poco a las personas que vienen de lenguajes más rígidos, como java, donde solo hay una forma correcta de hacer las cosas. Sin embargo, en realidad, también en js convendría seguir una manera u otra... solo que depende del uso que vayamos a dar los objetos. Veamos un par de casos prácticos, los cuales, además, nos servirán para comprender un poco mejor qué es la «encapsulación».

1. Objetos mediante notación de literales

Declarar un objeto mediante literales es muy ágil, pero el problema es que si cambiamos el valor de una propiedad durante el proceso, este cambio afecta al propio objeto, por lo que se pierde la idea de encapsulación, fundamental en la programación orientada a objetos, y que, recordemos viene a ser el aislamiento de determinados métodos y propiedades para que solo funcionen dentro de una clase, de tal manera que no puedan ser alterados de forma accidental en alguna parte del código.

var miObjeto = {

foo: 1,

bar: 2,

foobar: function() {

return this.foo+this.bar;

}

}

console.log( miObjeto.foo ) // 1

console.log( miObjeto.foobar() ) // 3

miObjeto.foo = 4;

console.log( miObjeto.foobar() ) // 6

Entonces, ¿cuándo conviene usar estos objetos?

Mi recomendación, cuando sea un objeto que sirva para transformar o chequear valores externos, es decir, para reunir utilidades que necesitaremos para trabajar los valores de otros objetos. Sería el equivalente en php a una clase estática.

Un ejemplo un poco chorra, pero que sirve para explicarme. Este objeto que comprueba el dispositivo del cliente -si es un navegador normal o móvil y el sistema operativo- podríamos hacerlo mediante notación de literales, ya que carece de propiedades internas, solo devuelve resultados.

var compruebaDispositivo = {

esMovil: function() {

if ( navigator.userAgent.match(/Android/i) !== null ) return true;

if ( navigator.userAgent.match(/(iPad)|(iPhone)|(iPod)/i) !== null ) return true;

return false;

},

esChrome: function() {

if ( navigator.userAgent.match(/Chrome/i) !== null ) return true;

return false;

},

esFirefox: function() {

if ( navigator.userAgent.match(/Firefox/i) !== null ) return true;

return false;

}

}

console.log(compruebaDispositivo.esMovil()); // true || false

console.log(compruebaDispositivo.esChrome()); // true || false

2. Mediante función constructora

A diferencia de la anterior, con este tipo de objetos, lo que suceda en una instancia no afecta al resto. Además, nos permite declarar variables privadas, inaccesibles desde fuera del propio objeto (por convención hungaresca, a veces se declaran comenzando por un guion bajo).

var otroObjeto = function() {

var _propiedadEncapsulada = 1;

this.propiedadAccesible = 2;

this.foobar = function() {

return _propiedadEncapsulada+this.propiedadAccesible;

}

}

miInstancia = new otroObjeto();

console.log(miInstancia._propiedadEncapsulada); // undefined

console.log(miInstancia.propiedadAccesible); // 2

console.log(miInstancia.foobar()); // 3

miInstancia.propiedadAccesible = 5;

console.log(miInstancia.foobar()); // 6

otraInstancia = new otroObjeto();

console.log(otraInstancia.propiedadAccesible); // 2

Estos objetos son muy robustos, pero también tienen un problema y es que en cada una de las instancias se «copia» toooodo el objeto original.

doble

Por lo tanto, aunque luego se puedan eliminar las instancias poniéndolas a null, estos objetos solo conviene utilizarlos cuando estemos seguros de que solo se va a sacar una instancia de ellos (como veremos en próximas entradas cuando hablemos de patrones de diseño).

3. Mediante prototipos

Este tipo de objetos es similar al anterior, pero en vez de declarar los métodos dentro del objeto, los vamos añadiendo mediante prototype. Algo así:

var otroObjetoMas = function() {

this.propiedad01 = 2;

this.propiedad02 = 4;

}

otroObjetoMas.prototype.metodoSumar = function() {

return this.propiedad01+this.propiedad02;

}

otroObjetoMas.prototype.metodoRestar = function() {

return this.propiedad01-this.propiedad02;

}

instancia01 = new otroObjetoMas();

instancia01.propiedad01 = 5;

console.log(instancia01.metodoSumar()); // 9

instancia02 = new otroObjetoMas();

console.log(instancia02.metodoSumar()); // 6

Y lo chulo de hacerlo así es que, al ser métodos prototipados, aunque no se «copian» en todas y cada una de las instancias, podemos utilizarlos porque los objetos tienen acceso a todos los métodos de su prototipo, como cualquier cadena de texto, por ejemplo, tiene el método replace() del prototipo original que es string.

solop

 

Bueno, espero que todo este lío haya quedado un poco más claro. En próximas entradas veremos nuevas maneras de armar objetos siguiendo patrones de diseño. Dejé todos los ejemplos anteriores en plunker.

|| Tags:

valoración de los lectores sobre JavaScript 00: 5. Algunos casos prácticos

  • estrellica valoración positiva
  • estrellica valoración positiva
  • estrellica valoración positiva
  • estrellica valoración positiva
  • estrellica valoración positiva
  • 5 sobre 5 (6 votos)

¿Te ha parecido útil o interesante esta entrada?
dormido, valoración 1 nadapensativo, valoración 2 un poco sonrisa, valoración 3 a medias guiño, valoración 4 bastante aplauso, valoración 5 mucho

Tú opinión es muy importante, gracias por compartirla!

Los comentarios están cerrados.