By now, I hope you've had a chance to read my friend Ryan's post on Javascript instantiation patterns. We're going to talk about Subclassing, and I feel it's important to have an understanding of Pseudoclassical Instantiation before moving forward.

What's a Subclass?

Imagine you're creating a racing game that will support a large amount of unique vehicles.

To start, let's define a car.

var Car = function(color){  
    this.color = color;
    this.maxSpeed = 100;
    this.seats = 4;
    this.wheels = 4;
    this.currentSpeed = 0;
}

Car.prototype.drive = function(){  
    this.currentSpeed = 60;
}

Car.prototype.boost = function(){  
    this.currentSpeed = this.maxSpeed;
}

Car.prototype.stop = function(){  
    this.currentSpeed = 0;
}

Great! To create a new car, we'll just say var redPlayer = new Car('red')

Now let's say we want to create a bluePlayer, but we want them to have a two-seat sports car.

var SportsCar = function(color){  
    this.color = color;
    this.maxSpeed = 120;
    this.seats = 2;
    this.wheels = 4;
    this.currentSpeed = 0;
    this.sunroof = 'closed';
}

SportsCar.prototype.drive = function(){  
    this.currentSpeed = 60;
}

SportsCar.prototype.boost = function(){  
    this.currentSpeed = this.maxSpeed;
}

SportsCar.prototype.stop = function(){  
    this.currentSpeed = 0;
}

SportsCar.prototype.openRoof = function(){  
    if (this.sunroof === 'closed'){
        this.sunroof = open;
    } else {
        alert('The sunroof is already open!');
    }
}

SportsCar.prototype.closeRoof = function(){  
    if (this.sunroof === 'open'){
        this.sunroof = 'closed';
    } else {
        alert('The sunroof is already closed!');
    }
}

Awesome! So to get one of these, we'll just say var bluePlayer = new SportsCar('blue')

Now how about a green player, but this time they're in a slower car that has a maximum speed of 80 instead? Or what about the yellow player, who happens to be on a motorcycle? A purple player in a truck?

...

See the problem? We're creating way too many classes that, more or less, do the same thing. This is a problem in programming, because one of the core principles is that you Don't Repeat Yourself (this is commonly referred to as 'DRY'). The idea behind DRY is that every time you find yourself repeating a good portion of code multiple times, there's going to be an easier way to do what you're trying to do.

Enter Subclassing.

Subclassing allows us to define one giant 'Superclass' with some default properties and methods, all of whom will naturally 'trickle down' to its Subclasses. If a Subclass happens to have a property or method which is already defined in its Superclass, the Subclass' definition will override the one in its Superclass.

Let's make our code above a lot more DRY.

We're going to start by defining a 'Vehicle' superclass. This allows us to create all types of vehicles: Cars, trucks, motorcycles, etc. without having to create a different superclass for each one, since they all more or less will share certain properties and methods.

var Vehicle = function(color){  
    this.color = color;
    this.maxSpeed = 100;
    this.seats = 4;
    this.wheels = 4;
    this.currentSpeed = 0;
}

Vehicle.prototype.drive = function(){  
    this.currentSpeed = 60;
}

Vehicle.prototype.boost = function(){  
    this.currentSpeed = this.maxSpeed;
}

Vehicle.prototype.stop = function(){  
    this.currentSpeed = 0;
}

Now that we've defined a Superclass, let's go and create a Subclass for our Sports Car.

First, we'll have the SportsCar constructor function call upon the Vehicle constructor function and pass in the color argument.

After that, I'm going to set the SportsCar prototype to the Vehicle prototype by using Object.create(). This will establish the relationship between Vehicle and SportsCar, allowing SportsCar to delegate to the Vehicle prototype for any methods.

Last step here: Setting the SportsCar prototype constructor to itself. This is especially helpful when we want to figure out exactly which function created an instance object.

The steps we have taken will create a SportsCar constructor with access to every single method and property that the Vehicle Superclass has.

var SportsCar = function(color){  
    Vehicle.call(color);
}

SportsCar.prototype = Object.create(Vehicle.prototype);  
SportsCar.prototype.constructor = SportsCar;  

Great! Now the next thing I want to do is adjust the number of seats and maximum speed for Sports Car, as well as add a sunroof to it. I can do that within the constructor function:

    this.maxSpeed = 120;
    this.seats = 4;
    this.sunroof = 'closed';

Perfect. Now to add the openRoof and closeRoof methods:

SportsCar.prototype.openRoof = function(){  
    if (this.sunroof === 'closed'){
        this.sunroof = open;
    } else {
        alert('The sunroof is already open!');
    }
}

SportsCar.prototype.closeRoof = function(){  
    if (this.sunroof === 'open'){
        this.sunroof = 'closed';
    } else {
        alert('The sunroof is already closed!');
    }
}

That's it! We've created a Superclass and assigned a Subclass to it. Simple as that, with much less lines of code, and we're already adhering to best practices.