2012-06-30 13 views
5

estoy tratando de crear una nueva clase que hereda Dog través de la herencia de prototipo de la clase Animal:¿Por qué no puedo heredar el prototipo de la clase Animal en mi código de JavaScript?

function Animal() { 
    this.name = "animal"; 
    this.writeName = function() { 
    document.write(this.name); 
    }  
} 

function Dog() { 
    this.name = "dog"; 
    this.prototype = new Animal(); 
} 

new Dog().writeName() 

JS Fiddle

Sin embargo, me sale un error de Javascript: Uncaught TypeError: Object #<Dog> has no method 'say'.

¿Por qué? ¿No debería el objeto Dog conservar un objeto Animal como prototipo?

+0

¿Seguro que pegó el código correcto? La palabra 'say' no aparece allí una vez. –

+0

Porque no hay clases? ;) Pero el problema es que 'this' ya es el * objeto incorrecto * en ese momento (así como el [[prototipo]] siendo * demasiado tarde * para que' new' se utilice). –

+2

BTW, use console.log en lugar de document.write y alerta. Hará tu vida mucho más fácil a largo plazo. – hugomg

Respuesta

3

@ respuesta de Ryan es correcta, por supuesto, pero en realidad no dicen lo que es diferente acerca de ello y puede que no sea evidente para un principiante, así que ...

El error que está haciendo es que this.prototype = new Animal(); asigna una instancia Animal a una propiedad denominada prototype de la corriente Dogejemplo (contempladas en el this), pero no hay nada especial acerca de una propiedad denominada prototype en este contexto.

La propiedad prototype es solo mágica en función objetos. Cuando crea una nueva instancia de SomeFunc utilizando new SomeFunc(), el puntero interno/oculto [[prototype]] del nuevo objeto se referirá al objeto al que apunta SomeFunc.prototype. El nombre prototype no es especial en ningún otro contexto.

+1

sí, tenía prisa, gracias por aclarar eso para él. – Ryan

2

La propiedad "prototipo" es solo una propiedad regular. La propiedad real [[Proto]] que trata con la delegación está oculta y no se puede manipular directamente después de crear un objeto (excepto con algunas extensiones: en Firefox, es la propiedad __proto__).

Una correcta Ejemplo de herencia de Javascript que es similar en espíritu a lo que está haciendo utilizaría Object.create para crear un perro con el correcto [[Prototype]] propiedad:

function Animal() { 
    this.name = "animal"; 
    this.writeName = function() { 
    document.write(this.name); 
    }  
} 

function Dog() { 
    var dog = Object.create(new Animal()) 
    dog.name = "dog"; 
    return dog; 
} 

(new Dog()).writeName() 

Un ejemplo más idiomática haría sea ​​algo así como la respuesta de Ryan, aunque recomendaría usar Object.create en lugar de new Animal para crear una instancia del prototipo de perro y pondría los métodos de animales en un prototipo de animal separado en lugar de unirlos manualmente en el constructor como lo está haciendo.

+0

@pst: Estaba hablando de cómo esperaba que la propiedad "prototipo" se comportara especialmente. – hugomg

+0

De acuerdo, eso es mejor, +1 :-) ¿Está disponible 'Object.create (proto)' [natively] en la 3ª edición? –

+0

@pst: No recuerdo ahora, pero es muy fácil escribir un polyfill para cuando no está disponible: https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Object/create#Polyfill – hugomg

7
function Animal() { 
    this.name = "animal"; 
    this.writeName = function() { 
    document.write(this.name); 
    }  
} 

function Dog() { 
    this.name = "dog"; 

} 
Dog.prototype = new Animal(); 
dog = new Dog(); 
dog.writeName(); 

ahora perro tiene todas las propiedades de los animales.

jsfiddle

Cuestiones relacionadas