En el siguiente código cuando hago console.log(teacher1.getDetails()); el valor de la propiedad se muestra indefinido, pero cuando hago console.log(teacher1.personName) o console.log(teacher.mainSubject) muestra el valor de la propiedad. ¿Que está sucediendo aquí? ¿Qué me estoy perdiendo? ¿Alguien puede explicarlo por favor? ¿Y cómo hacer que funcione?
let Person = function(personName, age) { this.personName = personName; this.age = age; }; Person.prototype.getDetails = function() { return `Person Name:${this.personName}. Age is ${this.age}.`; }; //Child constructor function let Teacher = function(personName, age, mainSubject) { Person.call(this, personName, age); this.mainSubject = mainSubject; }; Teacher.prototype = Object.create(Person.prototype); //inheritance Teacher.prototype.getDetails = function() { return `${this.__proto__.getDetails()} Main subject is ${this.mainSubject}.`; //optionally invoke the parent method. }; let teacher1 = new Teacher("Sakib", 35, "Physics"); console.log(teacher1.getDetails()); //invokes Teacher.getDetails() method (child's method).Debe implementar el método getDetails en la clase Teacher de esta manera:
Teacher.prototype.getDetails = function() { return `${Person.prototype.getDetails.call(this)} Main subject is ${this.mainSubject}.`; }Su implementación no funciona debido a lo siguiente: llama al método principal con respecto al contexto principal que no tiene valores definidos porque en el constructor del maestro define valores con respecto al contexto secundario.
Person.call(this, personName, age);Ejemplo de trabajo:
let Person = function(personName, age) { this.personName = personName; this.age = age; }; Person.prototype.getDetails = function() { return `Person Name:${this.personName}. Age is ${this.age}.`; }; //Child constructor function let Teacher = function(personName, age, mainSubject) { Person.call(this, personName, age); this.mainSubject = mainSubject; }; Teacher.prototype = Object.create(Person.prototype); //inheritance Teacher.prototype.getDetails = function() { return `${Person.prototype.getDetails.call(this)} Main subject is ${this.mainSubject}.`; //optionally invoke the parent method. }; let teacher1 = new Teacher("Sakib", 35, "Physics"); console.log(teacher1.getDetails()); //invokes Teacher.getDetails() method (child's method).Problemas en tu código:
this.__proto__.getDetails() no llama directamente a la función getDetails definida en Person.prototype porque en la primera invocación de la función getDetails() , this.__proto__ devuelve Teacher.prototype . Como resultado, this.__proto__.getDetails() se invoca a sí mismo, es decir, Teacher.prototype.getDetails()
Cuando se llama a Teacher.prototype.getDetails() por segunda vez, this.__proto__ ahora se refiere a Person.prototype porque this es Teacher.prototype y su prototipo es Person.prototype .
La segunda llamada a Teacher.prototype.getDetails() invoca la función Person.prototype.getDetails()
Debe vincular this para asegurarse de que el valor de this dentro de Person.prototype.getDetails() sea correcto
No deberías usar __proto__ - está en desuso. Use Object.getPrototypeOf() para obtener un prototipo de un objeto
Código fijo:
let Person = function(personName, age) { this.personName = personName; this.age = age; }; Person.prototype.getDetails = function() { return `Person Name:${this.personName}. Age is ${this.age}.`; }; let Teacher = function(personName, age, mainSubject) { Person.call(this, personName, age); this.mainSubject = mainSubject; }; Teacher.prototype = Object.create(Person.prototype); Teacher.prototype.constructor = Teacher; Teacher.prototype.getDetails = function() { const personPrototype = Object.getPrototypeOf(Object.getPrototypeOf(this)); return `${personPrototype.getDetails.call(this)} Main subject is ${this.mainSubject}.`; }; let teacher1 = new Teacher("Sakib", 35, "Physics"); console.log(teacher1.getDetails());