
Learning how to code — Fundamentals part 2
The decision of learning to code varies from one person to another. In my case, it is my thirst for logic, problem solving, and anything involving mind meddling that has made me slowly, but naturally gravitate towards it. The trigger, however, has been my newfound will to gain a better understanding of the intricacies behind some of the things that are often taken for granted in my day to day work.
I also strongly believe coding is empowering.
Thank you, Sun, for this unique learning opportunity. I’m thrilled I get to share my learnings with you fellow coding ninjas in the making. Let’s do this!
Recap: classes
Before we jump into new material, let’s do a quick recap of classes. In the last lesson, we left off by creating a class in which the constructor defined properties that enabled us to make different instances of the class Cup.
Before we move forward, you may have wondered, like me, what in the world this is? this is used to define our instance properties. When we write this.color = color;, we are defining the property color of our Cup instance by the value of the variable color.
Introducing instances
Instances are objects that belong to a class.
In our previous example, we created 2 instances: 1 white 500 ml cup, and 1 purple 250 ml cup.
console.log(new Cup(‘white’, 100));
console.log(new Cup(‘purple’, 500));As seen in the line of code above, we instantiated our instances using new Cup(‘white’, 100) and new Cup(‘purple’, 500), respectively, and output their properties using console.log. Now, what if we have a change of heart and want to change the color of our white 100ml cup to pink? Since we instantiated our cups inline without referring to them using variables, we can’t change their properties. This is where var comes back in.
If you run this, you’ll see we have 2 identical cups (notice the x2 on the bottom right hand corner?). We are creating 2 identical instances, but one of them can be referred to using the variable firstCup, which will give us more flexibility in our program later on. Let’s look at exactly what happened in the program above.
console.log(new Cup (‘white’,100));The above line of code should look familiar. This is how we made our cups in our previous lesson (defining the properties of our Cup instance inline).
var firstCup = new Cup (‘white’, 100);
console.log(firstCup);The firstCup we are creating above is a variable. This means we can go back to it and modify its properties later on. To output our instance, we must use console.log.
So far, the properties we defined in the class above are properties that can be defined by the user. Let’s now add some properties to our class that cannot be modified by the user when instantiating instances of Cup.
We’ve added 3 more properties to our class: content, creator and createdAt. All instances in our class will now have these hardcoded properties: they all contain ‘coffee’, are all created by ‘Sasha’ and their date of creation will be the exact moment we instantiated them.
Your turn, create a notebook that outputs a yellow 400ml capacity cup of coffee created by you with the date of creation being the moment you instantiate it and paste a link to it in the comments.
Setting vs. Getting instance properties
So far we’ve set properties to our different cups (instances). We can also get properties from an existing instance.
In the last line of code, we went to get (think of it as retrieving) the color of firstCup thanks to the color property. The second output you see when you run this will simply be the color pink.
Now that we have our pretty pink cup, wouldn’t be nice to fill it up with some coffee? I need my caffein fix already. In order to do this, we need to introduce the concept of class methods.
Introducing class methods
Class methods— a set of functions used to perform tasks on an object. Methods are an object property.
Let’s break this down to get a clearer picture of what’s going on.
You already know the color, capacity, content, creator, and createdAt properties, but a new property sneaked its way into our class: volume.
this.volume = 0; // volume in milliliters in the cup (by default the cup is empty)We previously defined our cup’s capacity property, but in order to fill our cup, we also need to know its volume. This is why we added a new property in our constructor: volume. We defined it as being empty by default (not user-defined).
fill(milliliters) {
this.volume += milliliters;
}The first method we are adding in our class is the fill(milliliters) function. In the above few lines of code, we said that the volume of the cup is defined in milliliters. The += adds whatever is on the right hand side of our line of code to the left hand side. Think of it as short for: volume = volume + milliliters.
drain(milliliters) {
this.volume -= milliliters;
}Here, we are setting the method for our function drain(milliliters). The same logic applies here: the -= substracts whatever is on the right hand side of our line of code from the left hand side. Think of it as short for: volume = volume - milliliters.
After defining firstCup variable var firstCup = new Cup(‘pink’, 100);, we can call our method fill(milliliters) to fill our cup.
firstCup.fill(50);
console.log(firstCup); // fill 50ml to the volume of our cup
firstCup.drain(10);
console.log(firstCup); // drain 10ml to the volume of our cupAfter filling our cup with 50ml, we used the method drain(milliliters) to decrease our cup’s volume by 10ml. The end result is therefore a pink 100ml capacity cup of coffee with 40ml in volume.
Your turn, create a notebook that outputs a blue 100ml capacity cup of coffee made by you, the date of creation being the moment you instantiate it, fill it with 70ml, proceed to drain it by 25ml, and paste a link to it in the comments.
Introducing conditions
Conditions — a state/expression that is either true or false
Filling and draining our cup is great, but what happens if we decide to fill a 100ml capacity cup with 500ml? A mess. What about draining a 50ml cup by 100ml? Yes, negative liquid volume is quite impossible.
This is where if (condition) and else conditional statements come into play. We will be adding these statements to our fill(milliliters) and drain(milliliters) functions to add warnings or prevent certain outcomes to the user by using exceptions, should he/she fulfill certain conditions.
Introducing console.warn
console.warnis similar toconsole.log, but flags the output as a warning.
Introducing exceptions
Exceptions are used to flag unrecoverable issues encountered by a program. When thrown (this is how they are triggered in code), the program stops running and outputs the issue.
Woah. That looks kind of overwhelming at first glance (I know!). Let’s break it up into more digestible parts.
You already know the first block in the program is our constructor. Nothing has changed here. The next 2 blocks are using the same 2 methods we used previously — fill(milliliters) and drain(milliliters) — except we are adding more intricacies within each.
var totalMilliliters = this.volume + milliliters;In order to know if the cup is overflowing or not, we must define a new variable, totalMilliliters. This is equal to this.volume (one of our cup properties) plus the amount of milliliters we add when we use our function fill(milliliters).
if (totalMilliliters > this.capacity) {
}Next, we use the if (condition) statement. The condition here is for our variable totalMilliliters to be greater thanthis.capacity (one of our cup’s properties). The if statement is therefore: if (totalMilliliters > this.capacity). The next part determines the outcome I want if this condition resolves to be true.
this.volume = this.capacityIf the cup overflows, the volume of the cup will be the capacity of my cup.
var overflow = totalMilliliters — this.volume;This is amount by which my cup is overflowing.
console.warn(‘cup is overflowing by ‘ + overflow.toString());Here we are using the warn function of the console object to output a warning to the user that the cup is overflowing. The warning will show the string ‘cup is overflowing by ‘ , followed by the + sign to concatenate the value of the overflow variable we have just defined in our previous line of code.
We can’t concatenate a string to a number, therefore we need to convert the value of overflow (a number) to a string using toString(). This method is used to stringify a number or array to text.
else {
this.volume += milliliters;
}In the event that the condition to our if (totalMilliliters > this.capacity) statement is false, the else statement will execute. In this case, we simply add the milliliters to the volume of the cup.
Now, let’s take a look at our drain(milliliters) function.
var totalMilliliters = this.volume — milliliters;When draining, our totalMilliliters will equal this.volume minus the amount of milliliter.
if (totalMilliliters < 0) {
throw new Error(‘negative volume is impossible’);
}Here, the condition to our if() statement is for totalMilliliters to be lesser than 0. When this condition is true, we want to generate an exception. We use the throw statement here, which will throw a new Error message to the user that reads ‘negative volume is impossible’. The throw statement also stops the program from executing further instructions.
else {
this.volume -= milliliters;
}Again, the else statement will be executed in the event that the condition to the if (totalMilliliters < 0) statement is false.
Let’s make some cups using fill and drain to see exceptions in action.
var firstCup = new Cup(‘pink’, 100);
firstCup.fill(1000); // fill 1000ml to the volume of our cup
console.log(firstCup);When instantiating this 100ml capacity firstCup, filling it by 1000ml, and outputting it, you’ll see the string “cup is overflowing by 900” appear. This is because the condition to our if (totalMilliliters > this.capacity) statement in our fill(milliliters) function was resolved as true. Following this string, our cup is still cast since this only causes a warning message according to our if (totalMilliliters > this.capacity) statement, and its volume is equal to its capacity (100ml).
firstCup.drain(100); // drain 100ml to the volume of our cup
console.log(firstCup);Here we are draining firstCup by 100ml, which results in a cup that has 0ml in content.
firstCup.drain(50); // drain 50ml to the volume of our cup
console.log(firstCup);When we drain firstCup by another 50ml, the condition to our if (totalMilliliters < 0) statement in our drain(milliliters) function is met, so an error is thrown, generating an exception which stops the rest of the program.
Extending classes
We extend a class by creating a class that is a child of another class
Now that we’ve successfully created a bunch of cups using the Cup class, let’s switch it up a notch and make bowls. Bowls are very similar to cups: they are concave, have volume and capacity, are of a certain color… Bowls thus share many of the same properties that already define our cups. I don’t know about you, but I’m a huge fan of eliminating double work.
class Bowl extends Cup {
}This is what we did above using the extends keyword to create a child class of our class Cup. This allows us to use the same properties for our bowls as we did for our cups, but we can still add additional properties, such as width, for our new class Bowl, if we wish to do so.
constructor(color, capacity, width) {
super(color, capacity);
this.width = width; // width in inches
}The constructor we are using for our bowls uses the super keyword to run the constructor method of our parent class Cup. You’ll notice we did not need to reference our other properties volume, content, creator and createdAt, because these are not user-defined. The last line of code here is the additional property we added to our bowls, which our cups do not have: width.
var firstBowl = new Bowl(‘red’, 500, 3);
firstBowl.fill(500); // fill 500ml to the volume of our bowl
console.log(firstBowl);We just made a red, 500ml capacity, 3in bowl! Our complete program now looks like this:
Notice in our program above that are using // to comment out the use of the drain(milliliters) function that had caused an exception. (Tip: to comment out one or more lines of code, simply select the lines you wish to comment out, and hit cmd+/). This is simply to prevent the exception from stopping our program from running.
// firstCup.drain(50); // drain 50ml to the volume of our cup
// console.log(firstCup);Your turn, create a notebook and create the Bowl class as an extension of the Cup class to cast a purple, 125ml capacity, 2in bowl. Paste a link to it in the comments.
We just made a neat little program here and learned important coding fundamentals. Give yourself a pat on the back.
Don’t hesitate to leave comments, share, and like! More to come soon, ninjas.
