Javascript
JavaScript Prototypal Inheritance that Works for All [The Ultimate Guide]

5c70aa1080b7f

OK, in JavaScript, actualizing OOP idea is a torment in the *ss particularly when you are doing this with ES5. Since JavaScript OOP design was very little all things considered in different language like C# and Java, JavaScript engineers will in general accomplish a greater amount of the works so as to change their way round the language while actualizing OOP. In ES6 Class was presented as a syntactic sugar for composing OOJS however this take care of a ton of issues, this does not ensure full highlights of OOP actualized in JavaScript, consequently toward the end, any Object made with the class assertion still falls back to Function Constructor.

Another huge issue JavaScript software engineers do have when endeavoring to execute OOP in JavaScript is Extending to or Inheriting from another Object, thus in this post I am going to hand out the correct method to do this.

Right off the bat, in JavaScript what we ought to comprehend is that there are numerous approaches to accomplish a specific assignment, numerous designers has had a go at taking care of this issue yet at times what they do is simply changing which Object this will point to utilizing the call Function technique. In reality that works however at some point when the undertaking gets greater you discover you need to rebuild numerous things due to the underlying oversight.

Here we go, lets state we have Our Base Object which will need to extend to or inherit from as Sports and in genuine Sports we have numerous games like football, ball, tennis and so on. Presently our Base Object will have a few properties like players, classes, stadiums and methods like countTeams(), countStadiums() and so on.

The explanation behind this is, we need once any games (tennis, football and so forth) inherits from the Sports which is the base class, they will have every one of those properties and methods inherited from their Base Class (Sports)

Initially, we make our Base class

// Super Object
function Sports () {
// Assign everything we want to share in the the prototype so that we can inherit everything from the Prototype

/**
 * Every member declared here will not be shared during
 * inheritance, Note that this behaviour does 
 * not make them private members since they can
 * still be use by only the instance of Sports but 
 * not by any Class that extends it 
*/
this.players = 0;
this.stadiums = [];
this.teams = [];
this.leagues = [];


this.updateName = function (name) {
    this.name = name;
  }
}

//Update the prototype and add what we are going to share with other class


Sports.prototype.countPlayers = function () {
 return this.players;
}

Sports.prototype.countTeams = function () {
  return this.teams.length;
}

Sports.prototype.countStadium = function () {
  return this.stadiums.length;
}

Sports.prototype.countLeagues = function () {
  return this.leagues.length;
}

Sports.prototype.addTeams = function (team) {
  return this.teams.push(team);
}

Sports.prototype.addStadium = function (stadium) {
  return this.stadiums.push(stadium);
}

Sports.prototype.addLeagues = function (league) {
  return this.leagues.push(league);
}

Sports.prototype.updatePlayers = function (players) {
  this.players = players;
}

Okay, now we are done with our Base Class (Sports)
Let's recap, in the code above we created Sports class, assigned every property and updateName method in its Constructor, these two members unlike in other languages like C#, PHP or Java, they can only be accessed by any object created from the instance of the Sports class but will not be shared to any class inheriting from the Sports class. Remember earlier in this post that I said JavaScript does fully support OOP like other language, so what we have above is one of the reasons.

Now let us create new classes that will extend to the Sports class

function Tennis () {
  // Let's assign own methods for this class
  this.ballSize = 30;
  this.players = 2; 
  this.teams = [
     'USA',
    'CHINA',
    'AUSTRALIA'
   ];

  this.stadiums = [
    'Main Stadium',
    'Major Stadium',
    ];
}

function Football () {
  // Let's assign own methods for this class
  this.ballSize = 30;
  this.players = 22;
  this.teams = [
    'Chelsea',
    'Man U',
    'Brazil',
    'New Castle'
];

this.stadiums = [
  'Main Stadium',
  'Major Stadium',
  'Indoor Stadium'
 ];
};

Our classes are ready, remember both classes only has properties without any method, since the methods are going to be used on both classes, there is no need creating the methods in each of the class again, that is why we created the Base class earlier so that both of the child class can inherit from it and use those methods in it's prototype. Now again we repeated the players, teams, stadiums properties in each of the class, this is because the Base class has those properties in it's Constructor and cannot be accessed by any of the class inheriting from it, hence we want to inherit from the base class in the future, to be able to use the count, add and update methods properly since they are updating the properties, we have to add the properties again in the child class so that the method will see them first to update, if not it will throw an error when trying to update or count the properties and this is not what we want since we can't access the Base Class Constructor members.

Inheriting from the Base Class is simple with a short code. There are many ways of doing this but am going to use the Object.create(obj);

According to MDN, The Object.create() method creates a new object, using an existing object as the prototype of the newly created object.

// Let us inherit from the Base class
Football.prototype = Object.create(Sports.prototype);
Tennis.prototype = Object.create(Sports.prototype);
// We are done with the inheritance
// Now can use all the methods from the Base class from any of the Child class object

// Let test on Footaball
let football = new Football();
football.countPlayers() // 22;
football.updatePlayers(21); 
football.countPlayers() // 21;
football.countTeams() // 4
football.addTeams('My team');
football.countTeams() //5
football.countStadium() // 3
football.addStadium('Another Stadium');
football.countStadium() // 4

// But we can't add Leagues or count leagues, because the property they are trying to update is in the Base Constructor and the child class cant acces them
football.addLeagues('Super League') // TypeError: this.leagues is undefined
football.countLeagues() // TypeError: this.leagues is undefined

// Let test on Footaball
let tennis = new Tennis();
tennis.countPlayers() // 2;
tennis.updatePlayers(6); 
tennis.countPlayers() // 6;
tennis.countTeams() // 3
tennis.addTeams('Another tennis team');
tennis.countTeams() //4
tennis.countStadium() // 2
tennis.addStadium('Another Stadium');
tennis.countStadium() // 3

// Same error when we try to use the addLeagues and countLeagues methods
tennis.addLeagues('Super League') // TypeError: this.leagues is undefined
tennis.countLeagues() // TypeError: this.leagues is undefined

Note, we are resetting the prototype of the Child class when we did Football.prototype and Tennis.prototype, so in case if we want to add anything in the prototype of the these two classes it must be after we have inherited from the Base class, if not the line which will inherited the Base Class will override everything in the prototype and reset it to the Base Class prototype, hence making it's initial prototype members undefined;

Example:

// Bad
Football.prototype.startTime = Date.now();
Football.prototype = Object.create(Sports.prototype); // Removes the startTime method when inheriting
Football.prototype.startTime; // undefined

// Good
Football.prototype = Object.create(Sports.prototype);
Football.prototype.startTime = Date.now();
Football.prototype.startTime; // Date.now()

From what we have above, you can see that both classes (Football and Tennis) has successfully inherited from the Sports Object as they are able to use the methods created in the Base class. But again they can't use the addLeagues() and countLeagues() methods, as stated in the comment section on the code, this is because the property they are about to update or count is in the Constructor of the base Class and they can't access them.

Again, the inheritance method above solve the basic inheritance problem but it creates another problem, how? When we did Football.prototype and Tennis.prototype we did not just reset only the prototypes but also the constructor of the prototype, which means when we do Football.prototype.constructor or Tennis.prototype.constructor it will give us Sports, but that is not what we want, because apart from instantiating an object with obj = new Object() we can also use obj = new Object.prototype.constructor() they are both the same but if we try this in with Tennis.prototype.constructor it won't yield the same result

let tennis = new Tennis(); //Created the Tennis Object

let tennisConstruct = new Tennis.prototype.constructor() // Creates the Sports Object

That is not fair, let us correct this by also resetting the prototype constructor of each of the class.

Note this will be done immediately after inheriting from the base class.

Now our inheritance will look like

// Let us inherit
Football.prototype = Object.create(Sports.prototype);
Football.prototype.constructor = Football;

Tennis.prototype = Object.create(Sports.prototype);
Tennis.prototype.constructor = Tennis;

As we have seen, Prototypal inheritance in JavaScript is not that hard just that some programmers tends to follow the difficult way.

Don't forget to air your views on this post.

![5c70aa1080b7f](serve/attachment&path=5c70aa1080b7f) OK, in JavaScript, actualizing OOP idea is a torment in the *ss particularly when you are doing this with ES5. Since JavaScript OOP design was very little all things considered in different language like C# and Java, JavaScript engineers will in general accomplish a greater amount of the works so as to change their way round the language while actualizing OOP. In ES6 Class was presented as a syntactic sugar for composing OOJS however this take care of a ton of issues, this does not ensure full highlights of OOP actualized in JavaScript, consequently toward the end, any Object made with the class assertion still falls back to Function Constructor. Another huge issue JavaScript software engineers do have when endeavoring to execute OOP in JavaScript is Extending to or Inheriting from another Object, thus in this post I am going to hand out the correct method to do this. Right off the bat, in JavaScript what we ought to comprehend is that there are numerous approaches to accomplish a specific assignment, numerous designers has had a go at taking care of this issue yet at times what they do is simply changing which Object this will point to utilizing the call Function technique. In reality that works however at some point when the undertaking gets greater you discover you need to rebuild numerous things due to the underlying oversight. Here we go, lets state we have Our Base Object which will need to extend to or inherit from as Sports and in genuine Sports we have numerous games like football, ball, tennis and so on. Presently our Base Object will have a few properties like players, classes, stadiums and methods like countTeams(), countStadiums() and so on. The explanation behind this is, we need once any games (tennis, football and so forth) inherits from the Sports which is the base class, they will have every one of those properties and methods inherited from their Base Class (Sports) Initially, we make our Base class ```` // Super Object function Sports () { // Assign everything we want to share in the the prototype so that we can inherit everything from the Prototype /** * Every member declared here will not be shared during * inheritance, Note that this behaviour does * not make them private members since they can * still be use by only the instance of Sports but * not by any Class that extends it */ this.players = 0; this.stadiums = []; this.teams = []; this.leagues = []; this.updateName = function (name) { this.name = name; } } //Update the prototype and add what we are going to share with other class Sports.prototype.countPlayers = function () { return this.players; } Sports.prototype.countTeams = function () { return this.teams.length; } Sports.prototype.countStadium = function () { return this.stadiums.length; } Sports.prototype.countLeagues = function () { return this.leagues.length; } Sports.prototype.addTeams = function (team) { return this.teams.push(team); } Sports.prototype.addStadium = function (stadium) { return this.stadiums.push(stadium); } Sports.prototype.addLeagues = function (league) { return this.leagues.push(league); } Sports.prototype.updatePlayers = function (players) { this.players = players; } ```` Okay, now we are done with our **Base Class (Sports)** Let's recap, in the code above we created Sports class, assigned every property and updateName method in its Constructor, these two members unlike in other languages like C#, PHP or Java, they can only be accessed by any object created from the instance of the Sports class but will not be shared to any class inheriting from the Sports class. Remember earlier in this post that I said JavaScript does fully support OOP like other language, so what we have above is one of the reasons. Now let us create new classes that will extend to the Sports class ```` function Tennis () { // Let's assign own methods for this class this.ballSize = 30; this.players = 2; this.teams = [ 'USA', 'CHINA', 'AUSTRALIA' ]; this.stadiums = [ 'Main Stadium', 'Major Stadium', ]; } function Football () { // Let's assign own methods for this class this.ballSize = 30; this.players = 22; this.teams = [ 'Chelsea', 'Man U', 'Brazil', 'New Castle' ]; this.stadiums = [ 'Main Stadium', 'Major Stadium', 'Indoor Stadium' ]; }; ```` Our classes are ready, remember both classes only has properties without any method, since the methods are going to be used on both classes, there is no need creating the methods in each of the class again, that is why we created the Base class earlier so that both of the child class can inherit from it and use those methods in it's prototype. Now again we repeated the players, teams, stadiums properties in each of the class, this is because the Base class has those properties in it's Constructor and cannot be accessed by any of the class inheriting from it, hence we want to inherit from the base class in the future, to be able to use the count, add and update methods properly since they are updating the properties, we have to add the properties again in the child class so that the method will see them first to update, if not it will throw an error when trying to update or count the properties and this is not what we want since we can't access the Base Class Constructor members. Inheriting from the Base Class is simple with a short code. There are many ways of doing this but am going to use the Object.create(obj); > According to MDN, The Object.create() method creates a new object, using an existing object as the prototype of the newly created object. ```` // Let us inherit from the Base class Football.prototype = Object.create(Sports.prototype); Tennis.prototype = Object.create(Sports.prototype); // We are done with the inheritance // Now can use all the methods from the Base class from any of the Child class object // Let test on Footaball let football = new Football(); football.countPlayers() // 22; football.updatePlayers(21); football.countPlayers() // 21; football.countTeams() // 4 football.addTeams('My team'); football.countTeams() //5 football.countStadium() // 3 football.addStadium('Another Stadium'); football.countStadium() // 4 // But we can't add Leagues or count leagues, because the property they are trying to update is in the Base Constructor and the child class cant acces them football.addLeagues('Super League') // TypeError: this.leagues is undefined football.countLeagues() // TypeError: this.leagues is undefined // Let test on Footaball let tennis = new Tennis(); tennis.countPlayers() // 2; tennis.updatePlayers(6); tennis.countPlayers() // 6; tennis.countTeams() // 3 tennis.addTeams('Another tennis team'); tennis.countTeams() //4 tennis.countStadium() // 2 tennis.addStadium('Another Stadium'); tennis.countStadium() // 3 // Same error when we try to use the addLeagues and countLeagues methods tennis.addLeagues('Super League') // TypeError: this.leagues is undefined tennis.countLeagues() // TypeError: this.leagues is undefined ```` >Note, we are resetting the prototype of the Child class when we did Football.prototype and Tennis.prototype, so in case if we want to add anything in the prototype of the these two classes it must be after we have inherited from the Base class, if not the line which will inherited the Base Class will override everything in the prototype and reset it to the Base Class prototype, hence making it's initial prototype members undefined; Example: ```` // Bad Football.prototype.startTime = Date.now(); Football.prototype = Object.create(Sports.prototype); // Removes the startTime method when inheriting Football.prototype.startTime; // undefined // Good Football.prototype = Object.create(Sports.prototype); Football.prototype.startTime = Date.now(); Football.prototype.startTime; // Date.now() ```` From what we have above, you can see that both classes (Football and Tennis) has successfully inherited from the **Sports Object** as they are able to use the methods created in the Base class. But again they can't use the addLeagues() and countLeagues() methods, as stated in the comment section on the code, this is because the property they are about to update or count is in the Constructor of the base Class and they can't access them. Again, the inheritance method above solve the basic inheritance problem but it creates another problem, how? When we did Football.prototype and Tennis.prototype we did not just reset only the prototypes but also the constructor of the prototype, which means when we do Football.prototype.constructor or Tennis.prototype.constructor it will give us Sports, but that is not what we want, because apart from instantiating an object with obj = new Object() we can also use obj = new Object.prototype.constructor() they are both the same but if we try this in with Tennis.prototype.constructor it won't yield the same result ```` let tennis = new Tennis(); //Created the Tennis Object let tennisConstruct = new Tennis.prototype.constructor() // Creates the Sports Object ```` That is not fair, let us correct this by also resetting the prototype constructor of each of the class. >Note this will be done immediately after inheriting from the base class. Now our inheritance will look like ```` // Let us inherit Football.prototype = Object.create(Sports.prototype); Football.prototype.constructor = Football; Tennis.prototype = Object.create(Sports.prototype); Tennis.prototype.constructor = Tennis; ```` As we have seen, Prototypal inheritance in JavaScript is not that hard just that some programmers tends to follow the difficult way. Don't forget to air your views on this post.
edited Mar 2 at 9:06 am
1
273
1
3
live preview
enter atleast 10 characters
WARNING: You mentioned %MENTIONS%, but they cannot see this message and will not be notified
Saving...
Saved
With selected deselect posts show selected posts
All posts under this topic will be deleted ?
Pending draft ... Click to resume editing
Discard draft