0

I have a function constructor defined this way:

var Person = function (name, yearOfBirth, job) {
            this.name = name;
            this.yearOfBirth = yearOfBirth;
            this.job = job;
        }
        Person.prototype.calculateAge = function () {
            console.log(2016 - this.yearOfBirth);
        };

Now I also have another function constructor called Teacher which I've defined this way:

var Teacher = function (name, yearOfBirth, subject) {
            Person.call(this, name, yearOfBirth, "teacher");
            this.subject = subject;
        }

Now I create a new object called roySir this way:

var roySir = new Teacher("Roy", 1960, "English");

However when I try to do roySir.calculateAge() I get an error saying that

"roySir.calculateAge is not a function"

How come the calculateAge function is not inherited here?

enter image description here

Another question I have is when I check:

roySir.hasOwnProperty("name") // true

Why is this true here? Isn't name a property of the parent class rather than an own property?

enter image description here

4
  • are you in a JS environment that supports the new ES6 class - much easier to do Commented Oct 3, 2018 at 2:52
  • no.. just following a tutorial.. but it doesn't go in to a lot of detail as to why this works the way it does.. Commented Oct 3, 2018 at 2:54
  • but it doesn't work? so the tutorial is flawed Commented Oct 3, 2018 at 2:56
  • no.. it works in the tutorial.. cuz they didn't have the prototype method.. i just added it myself as a learning exercise.. Commented Oct 3, 2018 at 2:58

1 Answer 1

2

You should ensure that Teacher's prototype inherits from Person's prototype. Simply calling Person with a Teacher won't let Teacher inherit from Person's prototype methods:

var Person = function(name, yearOfBirth, job) {
  this.name = name;
  this.yearOfBirth = yearOfBirth;
  this.job = job;
}
Person.prototype.calculateAge = function() {
  console.log(2016 - this.yearOfBirth);
};
var Teacher = function(name, yearOfBirth, subject) {
  Person.call(this, name, yearOfBirth, "teacher");
  this.subject = subject;
}
Teacher.prototype = Object.create(Person.prototype);
var roySir = new Teacher("Roy", 1960, "English");
roySir.calculateAge();

You need the Object.create rather than Teacher.prototype = Person.prototype there so that mutations to Teacher.prototype won't undesirably change Persons that aren't Teachers - for example, if you gave Teacher.prototype a teachesClass method, you would want only Teachers to have access to that, but you wouldn't want a generic Person to have that method.

Alternatively, use ES6 and extends, which is more readable:

class Person {
  constructor(name, yearOfBirth, job) {
    this.name = name;
    this.yearOfBirth = yearOfBirth;
    this.job = job;
  }
  calculateAge() {
    console.log(2016 - this.yearOfBirth);
  }
}
class Teacher extends Person {
  constructor(name, yearOfBirth, subject) {
    super(...[name, yearOfBirth, subject, 'teacher']);
  }
}
var roySir = new Teacher("Roy", 1960, "English");
roySir.calculateAge();

As for the name property, it's assigned to the object itself with this.name = name; - when a constructor is called, like with Person.call(this, ...), the this in the other constructor still refers directly to the object being created in the calling code - that's what call does, the first argument passed to it will be a direct reference to the this used in the other function.

The prototype chain looks like:

roySir { name, yearOfBirth, job }
above inherits from Teacher.prototype (empty)
above inherits from Person.prototype { calculateAge }
Sign up to request clarification or add additional context in comments.

3 Comments

why did you do Teacher.protoype = Object.create(Person.prototype).. can I just say Teacher.prototype = Person.prototype; ?.. are they same thing?
See edit - if you do that, mutations to Teacher.prototype will undesirably change Person.prototype as well - you won't be using inheritance, you'll just be overwriting the other prototype object.
Yes I was just reading the edit. Thank you so much for making that clear. could you also please answer my other question about hasOwnProperty... ? :)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.