Workout and Boxing example for JS prototype and class

Workout

First we have the Workout function class. Its declaration acts as the constructor.
We have three properties: title, datetime, and notes.

Setting the Prototype to a object literal

First, let’s define the function class Boxing. We will instantiate it, and pass it for Workout.prototype to point to.

set Workout’s prototype to a Boxing literal object

Now, the hierarchy looks like this:

All instantiation of Workout will share that literal object of type Boxing.

note:

The reason why we have a constructor property from var b is because var b (new Boxing) is the object for Workout Prototype. Thus, even though Workout is using a Boxing literal object to represent for its prototype functionality, its purpose is to be that of the Workout Prototype.

Thus, if we are to have a constructor property pointing back to Workout, any future instantiations of Workout will correctly show Workout, instead of Boxing.


output:

Workout {
price: 883,
coach: ‘Joel’,
friends: [ ‘Allen’, ‘Bundy’ ],
_display: [Function],
constructor: [Function: Workout] }
Workout {
title: ‘Monday Workouts’,
datetime: 2018-02-05T10:11:41.560Z,
notes: ’10x calisthentics’,
setNotes: [Function],
display: [Function] }

Getting property for object with prototype

Instantiate Workout and Get a property

1) Instantiate a Workout object. It basically creates an object from our definition of Workout.

2) Then let’s try using the setNotes function.

We pass in the string to newNote. In the function the ‘this’ evaluates to our Workout instantiation. We check to see if property ‘notes’ exist in Workout. It does, and we set it to our string.

We can log properties of Workout like so:


output:
boxing workout #38
2018-02-05T03:37:56.585Z
100 rounds of sparring

We then come back out to main. Since our prototype is set to Boxing object literal, let’s see what happens when we try to access property coach.

It displays the string “Joel”.

  • First, it will see if the property “coach” exists in the Workout object. It does not.
  • Because it does not, it will go to its prototype and check there.
  • The prototype object is Boxing. And Boxing does have “coach” property initiated to Joel.

Hence, “Joel” is displayed.

Keep in mind that all instantiations will share this Boxing object literal.
If we were to create another Workout object, it will display the same coach.


output:
boxinglesson1.coach: Joel
boxinglesson2.coach: Joel

Let’s evaluate the prototype to see what it looks like:


Boxing {
price: 883,
coach: ‘Joel’,
friends: [ ‘Allen’, ‘Bundy’ ],
_display: [Function] }

Let’s change the coach property to someone else:

Now, as you can see, we literally changed the prototype’s property to something “Rex”. And this gets reflected to other instantiations has their prototype property set to this object.


output:
Boxing {
price: 883,
coach: ‘Rex’,
friends: [ ‘Allen’, ‘Bundy’ ],
_display: [Function] }


boxinglesson1.coach: Rex
boxinglesson2.coach: Rex

code:

Calling prototype object’s functions

Let’s set the coach property back to Joel

Let’s look at prototype function _display

We must take heed that the this in the function belongs to the instantiated object, NOT the prototype. In our case, ‘this’ is an instantiation of Workout.

Thus, when we try to do something like this.coach, it will first check Workout object to see if it has a property called coach.

Because it does not, it will then go to the prototype and check for a coach property. In our case, it does.

Therefore, in our function, this.coach is valid (Joe) and thus, will display Joel in the function.

You will also notice we check if to see if this.display is a function. The this in question is the instantiation of Workout. Thus, we are asking Workout if it has a display function. It evaluate to true, and thus, we call Workout’s display function.

output
Boxing::_display() – display() function declared
— Workout::display(): boxing workout #38 —
@ approximately : Mon Feb 05 2018 11:43:48 GMT+0800 (CST), you will be doing:
100 rounds of sparring
Workout::display() – Your coach is: Joel
Workout::display() – Your price is: 883
————————–

Setting Properties for Objects with Prototype

When we were getting properties, JS first evaluates your instantiated object. Then if it doesn’t exist, it will go up to the prototype object. If it doesn’t exist there, then it will return undefined.

When we’re setting properties, its much more limited. Due to all instantiations share a common prototype object

we cannot set/change a prototype property through an instantiation of an object.

The only way to do is through accessing the prototype object itself like so:

Then, all instantiations of Workout will have prototype property coach “Katu”.

If you were to try to set a prototype property like this:

At first, you may think you have successfully set the prototype’s coach property.


output
—————-Boxing::_display()————–
Your cost: 883
You will be coached by: Sismundo
~~~ Boxing workout # 2 / 24
Boxing::_display() – display() function declared
— Workout::display(): boxing workout #12 —
@ approximately : Mon Feb 05 2018 11:58:22 GMT+0800 (CST), you will be doing:
Run 10 kms
Workout::display() – Your coach is: Sismundo
Workout::display() – Your price is: 883
————————–

But upon closer inspection, you’ll see that instantiations DO NOT allow you to set its prototype’s properties.

Instead, because you try to set a property that does not exist at the instantiation level, it will add the property for you. In our example, it added property coach to your Workout instantiation.