ES6 classes and prototypes

For those of you who come from a object oriented programming language such as Java, C# and the likes, you tend to think about classes! now i’m sure you would all agree that when it comes to classes, Javascript is uh weird?. Today we’ll be looking at one of the significant upgrades to the Javascript language, the Es6 upgrades to be more precise, along with the new features, Es6 gave Javascript programmers the ability to declare classes (well sort of..). lets dig in!

Creating a class
class Vehicle{
 //members and functions here	
}

We simply declare a class using the “class” keyword followed by the name of the class, in our case it’s called Vehicle.

Adding fields
class Vehicle{
	constructor (name, wheels){
		this.name= name;
		this.wheels = wheels;
	}	
}

Line 2 adds a “constructor”, for those of you who are new to programming, a constructor is a simple block of code (a special block of code to be more precise) that runs every time a class is instantiated. Here we add two fields “name” and “wheels”. Once a object of the class Vehicle is created (instantiated) the constructor runs and accepts two parameters “name” and “wheels” which in turn sets them up using the “this.variableName” syntax. in our case “this.name” and “this.wheels”

Instantiating a class

Trust me this is one of those fancy words you hear in programming, what this simply means is creating objects from predefined classes. in other words, using the class you created.

class Vehicle{
constructor (name, wheels){
		this.name= name;
		this.wheels = wheels;
	}
}

let car = new Vehicle("Toyota", 4);
console.log(car.name); // Toyota
console.log(car.wheels); // 4

Line 8 creates a new object of the class Vehicle, when you look at it, a Car is a type of vehicle, makes sense, so its a instance of the class Vehicle. We also pass it the values “Toyota” and “4” which are passed along to the constructor on Line 2. Note that when Line 5 runs, the constructor is called once for every object created (instantiated). Line 6 and 7 prints the properties of the object car

Adding class methods
class Vehicle{
constructor (name, wheels){
		this.name= name;
		this.wheels = wheels;
	}

	move(){
	console.log(`Vroom! i'm a brand new ${this.name} vehicle`);
    }
}


let car = new Vehicle("Toyota", 4);
console.log(car.move()); // Vroom! i'm a brand new Toyota vehicle

Line 7 simply adds a new method or a member function called “move”. Notice the use of back ticks in Line 8 “, we skip the usual string delimiter “” and use a new Es6 feature called Template literals, this gives you the ability to interpret variables and expressions within strings. Head over to line 14 and we call the method on a instance of the class.

Extending classes
class Vehicle{
constructor (name, wheels){
		this.name= name;
		this.wheels = wheels;
	}

	move(){
	console.log(`Vroom! i'm a brand new ${this.name} vehicle`);
    }
}

class Plane extends Vehicle{
	
}

let aircraft = new Plane("F-22A Raptor", 3);
console.log(aircraft.name); // F-22A Raptor
console.log(aircraft.wheels); // 3

Extending classes is one of the major reasons why we would ever bother with creating them in the first place. Instead of declaring a whole class all over, why not borrow existing functionalities from an already existing one? Line 12 creates a new class using the “extends” keyword. A plane is a type of vehicle, but it’s in its own league. Creating a separate class for Planes makes perfect sense. Note that we get the same functionalities right out of the box as demonstrated by Line 17 and 18

There’s really no point extending a class if all we are going to use are the same old basic functionality of the old class we are extending from (Vehicle class). Below is an updated code of the Plane class

class Plane extends Vehicle{

	constructor(name, wheels, ability) {
	 super(name,wheels)
     this.ability=ability;
	}
	
	move(){
	    console.log(`Swoosh! I'm a super fighter jet ${this.name} with the ability of ${this.ability}`);
	}
}

Quite a lot is going on here. A Plane compared to a car obviously can do a lot more. We would like to show this and while we are at it, we want a custom message when we call the move method

Line 3 calls the constructor method and passes three parameters “name”, “wheels” and “ability.” Looking at the Plane class, “ability” is the functionality unique to the plane class and basically sums up the term “extending a class”.

As you already know, the job of a constructor is to wire up (calling it bootstrapping also works) the details of a class, but here is where it gets interesting, Line 4 uses a new keyword called “super”. Think of this as a contract, terms and conditions blah blah blah, when extending a class, the moment you call the constructor, you must reference the constructor of the class you are extending, in our case we use the keyword “super”. So what is basically happening on Line 4 is, The Plane class is about wiring up itself, The plane class constructor goes through the parameters passed to it and says, “Hey Vehicle class! I believe the variables “name” and “wheels” belong to you, could you set it up for me? here you go!”. Remember “ability” belongs to the Plane class and not the Vehicle class so it doesn’t bother passing it up to the Vehicle class. Instead it sets it up on Line 5.

When extending a method or member function of a class, you simply use the same method name and change the functionality. In our case, Line 8-9 logs a different message that is unique to the Pane class. There, you all caught up!

Instantiating and calling the various methods of our newly created extended class gives you the expected results as described below on Line 24-28

class Vehicle{
constructor (name, wheels){
		this.name= name;
		this.wheels = wheels;
	}

	move(){
	console.log(`Vroom! i'm a brand new ${this.name} vehicle`);
    }
}

class Plane extends Vehicle{
	constructor(name, wheels, ability) {
	 super(name,wheels)
     this.ability=ability;
	}
	
	move(){
		console.log(`Swoosh! I'm a super fighter jet ${this.name} with the ability of ${this.ability}`);
	}
}


let aircraft = new Plane("F-22A Raptor", 3, "flight");
console.log(aircraft.name); // F-22A Raptor
console.log(aircraft.wheels); // 3
console.log(aircraft.ability); // flight
aircraft.move(); // Swoosh! I'm a super fighter jet F-22A Raptor with the ability of flight
Static methods

We create static methods when we basically want to use a class for it’s method (utility class). We simply have no interest in instantiating it, we want to call out a functionality simply by using “Class.methodName” instead of “Object.methodName” (I think i lost you there). Lets quickly take a look at a code that explains this

Updated Vehicle class

class Vehicle{
constructor (name, wheels){
		this.name= name;
		this.wheels = wheels;
	}

	move(){
	console.log(`Vroom! i'm a brand new ${this.name} vehicle`);
    }

    static dict(){
    	console.log("A thing used for transporting people or goods");
    }
}


let car = new Vehicle("Toyota", 4);
console.log(car.move()); // Vroom! i'm a brand new Toyota vehicle
Vehicle.dict(); // A thing used for transporting people or goods
Vehicle.move(); //Error!! Uncaught TypeError:

Line 11 shows the addition of a new method, but notice the use of a new keyword “static”, yup! that’s how you declare a static method. but whats so special about it? glad you asked, head over to Line 19 and boom! there you have it. I called the method of the class directly (Class.methodName == Vehicle.dict()), without instantiating the class or in our case using an already instantiated class object i.e (Object.methodName == car.dict()). Line 20 throws a nasty javascript error, we tried calling a method that has not been declared static, in order to access the move method, I must instantiate the class (create a Vehicle object).

That pretty much sums up ES6 classes for this tutorial, for the sake of reference, below is the completed class code base.

class Vehicle{
constructor (name, wheels){
		this.name= name;
		this.wheels = wheels;
	}

	move(){
	console.log(`Vroom! i'm a brand new ${this.name} vehicle`);
    }

    static dict(){
		console.log('hello theres');
	}
}

class Plane extends Vehicle{
	constructor(name, wheels, ability) {
	 super(name,wheels)
     this.ability=ability;
	}
	
	move(){
		console.log(`Swoosh! I'm a super fighter jet ${this.name} with the ability of ${this.ability}`);
	}
}

Now that you understand ES6 classes, what’s next? simple, go brag to your friends about your new found knowledge!. Then you come back running, crying “Dupree, my buddie said he was creating classes long before ES6, how is that even possible!” Not my fault, you failed to look under the hood. always look under the hood! luckily, that’s why i’m here 😀

Javascript Prototypes
Posted in Javascript, Programming.