Classes & Javascript relations

Javascript uses objects for everything, these objects are based on prototypes, their definitions, which are also objects.

You can create an object and extend it’s prototype,
then instantiate this object to get an instance of this prototype. Just like any class definition & instance you can then have the instance operate independently of the prototype.

classes
So the first thing is the class definition, in javascript, this is a function. You give a function your class name and any member variables & default values can be set inside this function.

function BaseClass()
{
    this.a = 'b';
}

Now to instantiate the class, much like C# syntax, you do the following:

var myObject = new BaseClass();

‘myObject’ will now have an ‘a’ property, with a value of ‘b’.

functions
To add functions we must extend the prototype:

function BaseClass()
{
    this.a = 'b'
}
BaseClass.prototype.log = function()
{
    console.log(this.a);
}

And similarly, to have this function use the console (a global variable most browsers provide for debugging) print our ‘a’ value we can simply use this:

var myObject = new BaseClass();
myObject.log();

static properties
Private static properties can be local variables inbetween the prototype functions, public static properties can be added to the class object instead of it’s prototype. Contrary to other languages these properties can not be accessed using the this. object at all and the private properties are just a hack by placing variables in a temporary scope so when later on dynamically altering the prototype these variables are still not acessible.

public statics

BaseClass.staticLogSomething = function()
{
    console.log('something');
}

private statics
These are often wrapped in a surrounding function like so (notice the return!):

var BaseClass = function()
{
    var privateStatic = 0;
    function BaseClass()
    {
        this.a = 'b'
    }
    BaseClass.prototype.log = function()
    {
        console.log(this.a);
    }
    BaseClass.staticLogSomething = function()
    {
        console.log(privateStatic);
        privateStatic += 1;
    }
    return BaseClass;
}();

subclassing
Subclassing actually means creating a new class and then extending it’s prototype with the base class prototype so we share it’s functions and even know it’s constructor.

Then inside the constructor function we can use the base class constructor to inherit all initialized member variables. The hacky statics as described above won’t transfer because they are members of the base class definition object, which is a level above the prototype (which is the bit we inherit).

function SubClass()
{
    BaseClass.call(this);
}
SubClass.prototype = Object.create(BaseClass.prototype);

That’s all there is to it. Now we can extend this function by adding properties, overriding properties, etcetera. This second subclass overrides the ‘a’ and ‘log’ properties and adds a ‘b’ property which is also logged.

function SubClass2()
{
    BaseClass.call(this);
    this.a = 'c';
    this.b = 'd';
}

SubClass2.prototype = Object.create(BaseClass.prototype);

SubClass2.prototype.log = function()
{
    console.log(this.a);
    console.log(this.b);
}

Now this is some test code, putting these three classes together you can clearly see the functionality:

var a = new SubClass();
a.log();
var c = new SubClass();
c.log(); // to prove the sub class has the base class data & functions
var d = new SubClass2();
d.log(); // to prove the sub class can override this data
console.log(d.a); // to prove things are accessable and 'c' == 'this' inside it's functions
d.a = 'f';
console.log(d.a); // to prove we can alter values
var e = new SubClass2();
console.log(e.a); // to prove that that does not affect the prototype

// now let's see what static's do when inherited
var iBase = new BaseClass();
var iSub = new SubClass();
BaseClass.staticLogSomething();
SubClass.staticLogSomething(); // this will trigger an error because staticLogSomething must be accessed by it's object, in this case the BaseClass defintion object

calling base functions
One last thing to add, when you wish to call a baseclass function inside your subclass, all you need to do is ‘call’ it’s function via the prototype and pass in a reference to this (and any other arguments after that).

So essentially Subclass2.log could have been this:

SubClass2.prototype.log = function()
{
    BaseClass.prototype.log.call(this);
    console.log(this.b);
}

Leave a Reply

Your email address will not be published. Required fields are marked *