2011-01-30 21 views
30

Me doy cuenta de que esto se ha preguntado cientos de veces, sin embargo, parece que no entiendo el concepto de "por qué" los prototipos en JavaScript son apropiados, como para imitar las clases (sí , Sé que JavaScript es un lenguaje basado en prototipos, lo he recogido mucho).Tratando de entender el punto de los prototipos en JavaScript

Al igual que muchas otras personas que se esfuerzan por hacer de JavaScript un lenguaje cotidiano que uso, estoy acostumbrado al estilo de clase OOP normal, ya que he jugado en Java (y he usado clases tanto en ActionScript como en PHP). Sin embargo, mientras yo pienso entiendo cómo funcionan los prototipos, no puedo entender por qué son necesarios.

Aquí está mi script de ejemplo de la forma en que estoy actualmente la comprensión de los prototipos en JavaScript:

var Apple = function() { 
    // An apple? 
}; 

Apple.prototype.color = "red"; 

Apple.prototype.changeColor = function(new_color) { 
    this.color = new_color; 
}; 
Apple.prototype.getColor = function() { 
    alert('color: '+this.color); 
}; 

var apple1 = new Apple(); 
var apple2 = new Apple(); 
apple2.changeColor("green"); 
apple1.getColor(); 
apple2.getColor(); 

... Yo había asumido que tal vez el prototipo significaba que compartía el mismo objeto en lugar de sólo la creación de un nuevo objeto cada vez; sin embargo, obviamente no es el caso, ya que tanto apple1 como apple2 tienen colores diferentes, aún (después de ejecutar dicho script).

Entonces escribió en lo que es más de una secuencia de comandos orientado a objetos:

var Apple = function() { 
    this.color = "red"; 

    this.changeColor = function(new_color) { 
     this.color = new_color; 
    }; 
    this.getColor = function() { 
     alert('color: '+this.color); 
    }; 
}; 

var apple1 = new Apple(); 
var apple2 = new Apple(); 
apple2.changeColor("green"); 
apple1.getColor(); 
apple2.getColor(); 

Con los mismos resultados (como se esperaba). ... ¿Por qué no se recomienda este último código? No tengo problemas para usar prototipos (suponiendo que los use correctamente), pero necesito entender el concepto de "por qué".

... ¿Alguna ayuda?

Respuesta

31

... Yo había asumido que tal vez el prototipo significaba que compartía el mismo objeto en lugar de sólo la creación de un nuevo objeto cada vez ...

lo hace. Hay un objeto prototipo que se comparte entre todas las instancias creadas desde el constructor.

... sin embargo, obviamente no es el caso, ya que tanto apple1 como apple2 tienen colores diferentes, todavía (después de ejecutar dicho script).

Para ciertos tipos (por ejemplo, número, booleano, null, undefined o cadena), cuando se cambia una propiedad que existe en el objeto prototipo a través de this.color por ejemplo, se creará una propiedad color en la instancia. El prototipo no se ve afectado, por lo que las nuevas instancias tendrán el color predeterminado definido en el prototipo.

Si ha actualizado un miembro de una matriz o un objeto que ha sido referenciado por una propiedad del objeto prototipo, el cambio se verá entre todas las instancias.

... ¿Por qué no se recomienda este último código?

Porque está construyendo nuevas funciones idénticas con la creación de cada nueva instancia en lugar de compartir una instancia de las funciones a través del objeto prototipo.


Para ampliar un poco más, me gustaría señalar que cuando su función es llamada como constructor utilizando la palabra clave new, this en el constructor es la nueva instancia. Por lo tanto, cualquier propiedad que agregue al this se agregará a la instancia.

var Apple = function() { 
     // Here "this" is the object being constructed. As such, we're adding 
     // a property "rotten" to every instance created 
    this.rotten = false; 
}; 

    // adding a "color" property to the prototype object 
Apple.prototype.color = "red"; 

    // set the property "color" on the instance to the value of "new_color" 
Apple.prototype.changeColor = function(new_color) { 
    this.color = new_color; 
}; 
    // first check to see if this instance has its own "color" property. If so, 
    // use it. If not, look at the prototype object to see if it exists. 
Apple.prototype.getColor = function() { 
    alert('color: '+this.color); 
}; 

// two new instances each have their own "rotten" property, and don't have a 
// "color" property. Both share the prototype object, so if "color" is 
// requested, it will come from there 
var apple1 = new Apple(); 
var apple2 = new Apple(); 

// This will add an "color" property to the "apple2" instance 
apple2.changeColor("green"); 

// Doesn't have a "color" property, so it looks to the prototype object 
apple1.getColor(); 

// Has a "color" property, so it uses that instead of the "color" on the prototype 
apple2.getColor(); 
+1

Eso realmente ayudó enormemente; gracias. Al hacer referencia a 'Apple.prototype.color', puedo ver que todavía es" rojo ", lo que reconfirma mi pensamiento original sobre los prototipos que hacen referencia a un solo objeto. Todavía es un poco confuso, ya que quiero especificar mis métodos directamente en ... bueno, funciones, pero creo que puedo estar aprendiendo el truco. Gracias de nuevo. – clicheName

+0

@clicheName: De nada. Actualicé con un poco más de información, pero parece que lo entendiste. – user113716

+0

¿Lo estoy entendiendo correctamente? Creo que son algo así como la variable estática y los métodos en Java que se comparten entre los objetos ... – Vishwanath

5

El prototipo le permite agregar métodos y propiedades a una clase y la aplicará no solo a la clase, sino también a cualquier instancia de objeto actual de esa clase.

+0

Explicación simple que lo deja en claro. –

Cuestiones relacionadas