Reputation: 412
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
Upvotes: 2
Views: 735
Reputation: 1074385
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.
Upvotes: 3