Javascript es un lenguaje orientado a objetos, en teoría, pero tiene una particularidad interesante, no posee clases, con lo cual la creación de objetos se hace de otras manera que como haríamos en C#.
Formas de crear objetos número uno, literal:
La notación literal es la más común y permite declarar un objeto a partir de una expresión JSON, por ejemplo de este modo
var persona = {};
persona.nombre = 'leonardo';
console.log(persona.nombre);
Esto nos lleva a dos conclusiones:
Es posible en la misma declaración incluir las propiedades y funciones, del siguiente modo:
var persona = {
nombre:'leonardo' ,
saludar:function(){
return 'hola mi nombre es ' + this.nombre;}
};
console.log(persona.saludar());
perfecto, es claro que podemos declarar tanto propiedades como funciones de un objeto con una expresión literal, un JSON, nuestros objetos serán mutales y se podrán agregar más miembros en cualquier momento.
Creación de objetos a partir de funciones, forma dos:
Una forma más natural (para los que venimos de C#) de crear objetos en javascript es a partir de una función constructor, el ejemplo anterior utilizando esta técnica sería así:
Persona = function (nombre){
this.nombre = nombre;
this.saludar = function()
{
return "hola mi nombre es " + this.nombre;
}
};
var persona = new Persona('Leonardo');
console.log(persona.saludar());
y obtenemos el mismo resultado, la ventaja de esta forma es que podemos crear muchos objetos iguales, por ejemplo así:
Persona = function (nombre){
this.nombre = nombre;
this.saludar = function()
{
return 'hola mi nombre es ' + this.nombre;
}
};
var leonardo = new Persona('leonardo');
var gabriel = new Persona('gabriel');
console.log(leonardo.saludar());
console.log(gabriel.saludar());
y todo funciona muy bien, ahora vamos a ver un poco qué pasa en el DOM

Vemos algo interesante: tanto la propiedad “nombre” como la función “saludar” se encuentran a nivel objeto y no a nivel función “Persona”, lo que significa que se crea una nueva copia de la propiedad y de la función para cada uno de los objetos que generemos a parir de la función, en principio es poco deseable.
Utilizando prototipos
La forma de tener miembros reutilizables es agregarlos al prototipo, del siguiente modo:
Persona = function (nombre){
this.nombre = nombre;
Persona.prototype.saludar = function()
{
return 'hola mi nombre es ' + this.nombre;
}
};
var leonardo = new Persona('leonardo');
var gabriel = new Persona('gabriel');
console.log(leonardo.saludar());
console.log(gabriel.saludar());
ahora si, vemos que la función saludar pertenece al prototipo (__proto__) al igual que la función constructor, lo cual implica que ambos objetos utilizan la misma copia de la función, mucho mejor.
Variables estáticas?
Algo así, la pregunta es: qué pasa si ponemos también la propiedad nombre a nivel prototipo?
Persona = function (nombre){
Persona.prototype.nombre = nombre;
Persona.prototype.saludar = function()
{
return 'hola mi nombre es ' + this.nombre;
}
};
var leonardo = new Persona('leonardo');
var gabriel = new Persona('gabriel');
console.log(leonardo.saludar());
console.log(gabriel.saludar());
Vemos que tanto __proto__ como los dos objetos tienen el mismo valor en la propiedad “nombre” es porque al se una propiedad dentro del prototipo es siempre la misma, con lo cual va a tomar el valor que se le asignó en última instancia para todos los objetos y el prototipo, en este caso “gabriel”
Hasta la próxima.
2011-11-26 EDIT: como me comenta Carlos por mensaje privado, no es correcto acceder al prototipo en la función constructor ya que se ejecutaría con cada nuevo objeto, en contra de la idea final que es usar la misma instancia de la función, el código correcto debería modificar el prototipo por fuera de la función constructor, de la siguiente manera:
Persona = function (nombre){
this.nombre = nombre;
};
Persona.prototype.saludar = function(){
return 'hola mi nombre es ' + this.nombre;
}
Gracias Carlos!