2

I'm learning JavaScript prototyping. Here Employee is parent, I inherited from it in my Programmer prototype, but when I try to run the favoriteLanguage method of my child prototype(i.e Programmer), it's showing that favoriteLanguage is not a function. I tried reading from Mozilla documentation, but I couldn't understand if the stuff was relevant or not! Can anybody help me in simple terms please!

Edit: I know I can use class, but I want to learn why it's not working in this case!

Here's the code:

function Employee(givenName, givenExperience, givenDivision){
    this.name = givenName;
    this.experience = givenExperience;
    this.division = givenDivision;
}

Employee.prototype.slogan=function(){
    return `I am ${this.name} and this company is the best`;
}

Employee.prototype.joiningYear=function(){
    return 2020 - this.experience;
}

function Programmer(givenName, givenExperience, givenDivision, language, github){
    Employee.call(this,givenName, givenExperience, givenDivision);
    this.language = language;
    this.github = github;
}

Programmer.prototype.favoriteLanguage = function(){   //Error part
    if (this.language == 'python'){
        return 'Python';
    }
    else{
        return 'JavaScript';
    }
}

Programmer.prototype = Object.create(Employee.prototype);
Programmer.prototype.constructor = Programmer;

//Object.setPrototypeOf(Programmer.prototype, Employee.prototype);

let arju = new Programmer("Arju Aman",0,"Developer","javaScript","arjuaman");

console.log(arju);
// console.log(arju.joiningYear());
// console.log(arju.slogan());

console.log(arju.favoriteLanguage());   //called here

5
  • 1
    Why not use classes dude? They're syntax sugar on this stuff and very readable. developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/… Commented May 26, 2021 at 12:23
  • 1
    I suspect that this line: Programmer.prototype = Object.create(Employee.prototype); overrides everything which was declared under ` Programmer.prototype so far. Try to switch the order! Commented May 26, 2021 at 12:24
  • 1
    @Glycerine I know I can use class, but am in learning phase and I wanna understand what's going wrong here! Commented May 26, 2021 at 12:26
  • 1
    @NirAlfasi Yeah that was the case exactly! Commented May 26, 2021 at 12:30
  • 1
    @ArjuAman - Other than the one mistake, congrats on getting the inheritance part of the above right. Most people don't, they do things like use new Employee to create the Programmer.prototype object, or don't call Employee from Programmer correctly, etc. You didn't. Nice one! Commented May 26, 2021 at 12:35

1 Answer 1

3

The problem is you're adding a property to the default Programmer.prototype object:

Programmer.prototype.favoriteLanguage = function(){
    // ...
}

...but a moment later you're completely replacing that object with a new object:

Programmer.prototype = Object.create(Employee.prototype);

The new object won't have the property you added to the old one.

To fix it, just move the Programmer.prototype = statement above the statement adding a property to it:

function Employee(givenName, givenExperience, givenDivision){
    this.name = givenName;
    this.experience = givenExperience;
    this.division = givenDivision;
}

Employee.prototype.slogan=function(){
    return `I am ${this.name} and this company is the best`;
}

Employee.prototype.joiningYear=function(){
    return 2020 - this.experience;
}

function Programmer(givenName, givenExperience, givenDivision, language, github){
    Employee.call(this,givenName, givenExperience, givenDivision);
    this.language = language;
    this.github = github;
}

// *** Moved
Programmer.prototype = Object.create(Employee.prototype);
Programmer.prototype.constructor = Programmer;

Programmer.prototype.favoriteLanguage = function(){
    if (this.language == 'python'){
        return 'Python';
    }
    else{
        return 'JavaScript';
    }
}

let arju = new Programmer("Arju Aman",0,"Developer","javaScript","arjuaman");

console.log(arju);

console.log(arju.favoriteLanguage());

However, you mentioned you're learning JavaScript. Since 2015, JavaScript has had a much simpler way of defining constructor functions and the prototypes they assign to new instances: class syntax:

class Employee {
    constructor(givenName, givenExperience, givenDivision) {
        this.name = givenName;
        this.experience = givenExperience;
        this.division = givenDivision;
    }

    slogan() {
        return `I am ${this.name} and this company is the best`;
    }

    joiningYear() {
        return 2020 - this.experience;
    }
}

class Programmer extends Employee {
    constructor(givenName, givenExperience, givenDivision, language, github) {
        super(givenName, givenExperience, givenDivision);
        this.language = language;
        this.github = github;
    }

    favoriteLanguage() {
        if (this.language == "python"){
            return "Python";
        } else{
            return "JavaScript";
        }
    }
}

let arju = new Programmer("Arju Aman", 0, "Developer", "javaScript", "arjuaman");

console.log(arju);

console.log(arju.favoriteLanguage());

The new syntax still does much the same thing (this is still prototypical inheritance, it still creates a constructor function with a prototype property that defines the object that new X will assign the new object, etc.) but it's much simpler to use, particularly when inheriting. It also supports private fields and methods now; the following three proposals have all landed in the specification:

Having truly private information without these is possible, but much more cumbersome.

Sign up to request clarification or add additional context in comments.

2 Comments

@ArjuAman - No worries! I've also added to the answer.
For what it's worth, I go into class syntax in detail in Chapter 4 of my recent book JavaScript: The New Toys, and I cover the private fields etc. in Chapter 18. Links in my profile if you're interested.

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.