Diferencias entre objetos y prototipos

Categories:

Objetos y Prototipos

Como sabemos en JavaScript se pueden crear objetos y también se pueden crear prototipos. ¿Cuál es la diferencia que existe entre los objetos y los protipos? ¿Cuándo conviene utilizar uno en lugar del otro?

// Clase que va a tratar las instancias como objetos
var Personaje = function() {
  // Atributos del personaje
  this.nombre

  // Métodos del personaje
  this.mostrar_nombre = mostrar_nombre

  
  function mostrar_nombre()  {
    alert( "Me llamo: " +  this.nombre)
  }
      
}

De manera general se puede decir cada objeto o instancia cuenta con los atributos y los métodos que están definidos en la clase.

// Clase donde  la funcionalidad 
// va a estar definida como prototipo.

var Personaje = function() {
  // Atributos del personaje
  this.nombre
}

Personaje.prototype = {
  mostrar_nombre: function ()  {
    alert( "Me llamo: " +  this.nombre)
  }    
}

Los objetos generados por prototipos tienen los atributos y métodos que están definidos en la clase pero los atributos y los métodos especificados en el prototipo se comparten entre las diferentes instancias. De esta manera se ocupa menos memoria al momento de contar con varias instancias dentro de un documento que utilice el script.

Es por esta razón que se puede decir que es conveniente utilizar prototipos si se considera que se va a utilizar más de una instancia del objeto o prototipo dentro del mismo documento.

Ejemplo objeto

var Personaje = function() {
  // Atributos del personaje
  this.nombre

  // Métodos del personaje
  this.mostrar_nombre = mostrar_nombre

  
  function mostrar_nombre()  {
    alert( "Me llamo: " +  this.nombre)
  }
      
}

var snoopy = new Personaje
snoopy.nombre = "snoopy"
snoopy.mostrar_nombre()

Object.keys(snoopy)
//=> ["mostrar_nombre", "nombre"]

/*
 Cada objeto creado va a tener un atributo nombre 
y un  método mostrar_nombre 
*/

Ejemplo prototipo

var Personaje = function() {
  // Atributos del personaje
  this.nombre
}

Personaje.prototype = {
  // Métodos del personaje como prototipo
  mostrar_nombre: function ()  {
    alert( "Me llamo: " +  this.nombre)
  }    
}


var snoopy = new Personaje
snoopy.nombre = "snoopy"
snoopy.mostrar_nombre()
Object.keys(snoopy)
//=> ["nombre"]

Object.keys(snoopy['__proto__'])
//=> ["mostrar_nombre"]

/*
Cada objeto creado va a tener un atributo nombre pero 
el método mostrar_nombre se va a compartir entre 
todos los prototipos. 
*/

Extender clases con prototipos

Otro uso de los prototipos es para extender objetos o prototipos sin modificar el código fuente. Como vimos en esta publicación incluso se pueden extender los tipos de datos básicos de JavaScript como números, arreglos, valores de verdad, cadenas de texto.

Supongamos que queremos agregar funcionalidad a la clase personaje sin modificar el código fuente original. Podemos utilizar cualquiera de las dos versiones del personaje y guardarlas en un archivo – personaje.js. Utilizando otro archivo – app.js – que se mandamos llamar después del archivo personaje.js en un documento html para asegurar que la clase personaje existe – podemos extender la funcionalidad creando métodos y asociándolos al prototipo de la clase personaje.

Una vez hecho esto, los métodos se pueden utilizar por los objetos / instancias de la clase.

Ejemplo extender clase con prototipos

Personaje.prototype.extender = function() {
  console.log("Utilizando prototipos se puede extender\nla funcionalidad del objeto \nsin modificar el código fuente ")
}

snoopy.extender()

De esta manera podemos elegir cómo crear las clases para definir a los objetos / prototipos además de que sabemos cómo extender la funcionalidad de nuestros objetos sin modificar el código fuente.