Un objeto es una estructura que contiene tanto variables (llamadas propiedades) como las funciones que manipulan dichas variables (llamadas métodos). A partir de esta estructura se ha creado un nuevo modelo de programación (la programación orientada a objetos) que atribuye a los mismos propiedades como herencia o polimorfismo. Como veremos, JavaScript simplifica en algo este modelo.
El modelo de la programación orientada a objetos normal y corriente separa los mismos en dos: clases e instancias. Las primeras son entes más abstractos que definen un conjunto determinado de objetos. Las segundas son miembros de una clase, poseyendo las mismas propiedades que la clase a la que pertenecen. En Javascript esta distinción se difumina. Sólo tenemos objetos.
Por si acaso ya lo hemos olvidado, recordemos ahora cómo se accede a los métodos y propiedades de un objeto:
objeto.propiedad objeto.metodo(parametros)
Bueno, vale, este apartado es un poco tonto. Pero no os preocupéis que los dos siguientes tienen mucho más contenido.
Vamos a aprender a hacer nuestros propios objetos. Ya habíamos visto como hacerlo por medio de literales, pero dado que es una solución bastante propietaria y poco flexible, estudiaremos el método normal de lograrlo mediante constructores.
Un constructor es una función que inicializa un objeto. Cuando creamos un objeto nuevo del tipo que sea, lo que hacemos en realidad es llamar al constructor pasándole argumentos. Por ejemplo, si creamos un objeto Array de esta manera:
vector = new Array(9);
En realidad, estamos llamando a un constructor llamado Array que admite un parámetro. Sería algo así:
function Array(longitud) { ... }
Vamos a crear nuestro primer objeto. Supongamos que queremos codificar en Javascript una aplicación que lleve nuestra biblioteca de libros técnicos, de esos de Informática. Para lograrlo, crearemos un objeto Libro que guarde toda la información de cada libro. Este sería el constructor:
function Libro(titulo, autor, tema) { this.titulo = titulo; this.autor = autor; this.tema = tema; }
Como vemos, accederemos a las propiedades y métodos de nuestros objetos por medio de la referencia this. Ahora podemos crear y acceder a nuestros objetos tipo Libro:
miLibro = new Libro("JavaScript Bible", "Danny Goodman", "JavaScript"); alert(miLibro.autor);
Sencillo, ¿no? Sin embargo, para disfrutar de toda la funcionalidad de los objetos nos falta algo. Ese algo son los métodos. Vamos a incluir uno que nos saque una ventana con el contenido de las propiedades escrito:
function escribirLibro() { alert("El libro " + this.titulo + " de " + this.autor + " trata sobre " + this.tema); }
Para incluirlo en nuestro objeto añadimos la siguiente línea a nuestra función constructora:
this.escribir = escribirLibro;
Y podremos acceder al mismo de la manera normal:
miLibro.escribir();
Una de las capacidades más empleadas de la programación orientada a objetos es la herencia. La herencia supone crear objetos nuevos y distintos que, aparte de los suyas propios, disponen de las propiedades y métodos de otro objeto, al que llamaremos padre.
Vamos a ver en nuestro ejemplo cómo se puede aplicar. En la actualidad, en muchos libros de informática, se incluye un CD-ROM con ejemplos y a veces aplicaciones relacionadas con el tema del libro. Si quisieramos tener también esa información nos sería difícil, ya que algunos libros tienen CD y otros no. Podríamos tener otro objeto, pero tendríamos que reproducir el código (al menos del constructor) y si cambiáramos algo del mismo en el objeto Libro también tendríamos que hacerlo en el nuevo. Lo mejor será crear un objeto que herede las características de Libro y añada otras nuevas.
function LibroConCD (titulo, autor, tema, ejemplos, aplicaciones) { this.base = Libro this.base(titulo, autor, tema); this.tieneEjemplos = ejemplos; this.tieneAplicaciones = aplicaciones; }
Y podremos acceder a las propiedades de Libro sin mayores problemas:
miLibro = new LibroConCD("JavaScript Bible", "Danny Goodman", "JavaScript", true, true); miLibro.escribir();
Existe otra manera de añadir métodos a nuestros objetos sin tener que tocar para nada el código del constructor ni, de hecho, el código del objeto ya escrito. Supongamos que queremos ampliar el objeto anterior añadiendo un método parecido a escribir() pero que nos indique algo sobre los atributos extra que tiene la nueva clase:
function escribirCD() { if (this.tieneEjemplos && this.tieneAplicaciones) alert("Este libro, " + this.titulo + ", tiene un CD completo."); else alert("El CD de este libro es normalito."); } LibroConCD.prototype.escribirExtra = escribirCD;
Ahora sólo tendríamos que llamarlo con el objeto miLibro:
miLibro = new LibroConCD("JavaScript Bible", "Danny Goodman", "JavaScript", true, true); miLibro.escribirExtra();
Como tenemos siempre acceso al código de nuestros objetos, el prototipado se usa, generalmente, como forma de añadir funcionalidad a los objetos predefinidos de Javascript.