Home > database >  Properties inside method showing undefined but working outside the methods . How to fix it?
Properties inside method showing undefined but working outside the methods . How to fix it?

Time:09-18

In the below code when I do console.log(teacher1.getDetails()); the property value shows undefined but when I do console.log(teacher1.personName) or console.log(teacher.mainSubject) it shows property value. What is happening here? What am I missing? Can somebody explain it please? And how to make it work?

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).

CodePudding user response:

You need to implement getDetails method in the Teacher class like this:

Teacher.prototype.getDetails = function() {
    return `${Person.prototype.getDetails.call(this)} Main subject is ${this.mainSubject}.`;
}

Your implementation doesn't work because of next: you call the parent method regarding parent's context which doesn't have values defined because in Teacher constructor you define values regarding the child context.

Person.call(this, personName, age);

Working example:

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).

CodePudding user response:

Problems in your code:

  • this.__proto__.getDetails() doesn't directly calls the getDetails function defined in Person.prototype because in the first invocation of getDetails() function, this.__proto__ returns Teacher.prototype. As a result, this.__proto__.getDetails() invokes itself, i.e. Teacher.prototype.getDetails()

    When Teacher.prototype.getDetails() is called for the second time, this.__proto__ now refers to Person.prototype because this is now Teacher.prototype and its prototype is Person.prototype.

    The second call to Teacher.prototype.getDetails() invokes the Person.prototype.getDetails() function

  • You need to bind this to make sure that value of this inside Person.prototype.getDetails() is correct

  • You shouldn't use __proto__ - its deprecated. Use Object.getPrototypeOf() to get a prototype of an object

Fixed Code:

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());

  • Related