Yes, finally! It’s time to show you all how to create your own Javascript classes. Unlike most object orientated programming and scripting languages, there is no concrete way to define a class. For example, in Java you’d do something like this:
public class Stuff extends AnotherClass{
public Stuff(){
// ...
}
// ...
} |
public class Stuff extends AnotherClass{
public Stuff(){
// ...
}
// ...
}
Javascript has the class (and other related) keywords, but they have not been implemented. Because of this, classes need to be defined in a slightly different manner. The first step is to create the initial class, using a function:
function Stuff(){
// ...
} |
function Stuff(){
// ...
}
This function is the only constructor for your class, so if you want more than one way to construct the class you need to play around with the parameters that are passed in.
As with other object orientated languages, you can use the ‘this’ keyword within your constructor. The ‘this’ keyword is the only way to set attributes on the constructed object (with the class construction method I’m using). It is also possible to define variables in the constructor (using the ‘var’ keyword) then make functions that are able to access these, but the code within the constructor can get messy. An example of this is:
function AClass(){
var something = 5;
this.getSomething = function(){
return something;
};
} |
function AClass(){
var something = 5;
this.getSomething = function(){
return something;
};
}
This results in ‘something’ being private, which may be a helpful thing for your script. Unfortunately, with my method (read on), it is impossible to see or do anything with these variables unless a public function is created in the constructor. I’d only recommend this method for smaller classes that don’t need to deal with a super class.
For larger classes, I’d recommend using the ‘prototype’ method of class construction. This is the method I use most often when dealing with Javascript classes. In this method, you create your function (as above) then set the prototype attribute on the created function object to an object containing all the functions you want for every object created, like so:
function MyClass(param1, param2){
this._p1 = param1;
this._p2 = param2;
}
MyClass.prototype = {
_p1:null,_p2:null,
getP1:function(){
return this._p1;
},
getP2:function(){
return this._p2;
}
}; |
function MyClass(param1, param2){
this._p1 = param1;
this._p2 = param2;
}
MyClass.prototype = {
_p1:null,_p2:null,
getP1:function(){
return this._p1;
},
getP2:function(){
return this._p2;
}
};
A simple notation I’ve seen used a fair bit with this method (and one that I use myself) is to make all private attribute and function names start with an underscore. This method also allows for inheritance in a simple way:
function AnotherClass(p1, p2, p3){
this._p1 = param1;
this._p2 = param2;
this._p3 = param3;
}
AnotherClass.prototype = new MyClass();
AnotherClass.prototype.getP3 = function(){
return this._p3;
}; |
function AnotherClass(p1, p2, p3){
this._p1 = param1;
this._p2 = param2;
this._p3 = param3;
}
AnotherClass.prototype = new MyClass();
AnotherClass.prototype.getP3 = function(){
return this._p3;
};
This unfortunately removes class privacy, since the subclass needs to know about the superclass’s ‘private’ fields. Personally, I haven’t used the inheritance model because of this. It’s still a very powerful tool in terms of being able to create a class hierarchy within your scripts.
To simplify creating classes, it is possible to make a function that does all the hard work of constructing your classes:
function createClass(obj){
// get the constructor
var theClass = obj.ctor || function(){};
// now the prototype
theClass.prototype = obj.instance || {};
// any any static variables or methods
if(obj.static){
for(var key in obj.static){
theClass[key] = obj.static[key];
}
}
return theClass;
} |
function createClass(obj){
// get the constructor
var theClass = obj.ctor || function(){};
// now the prototype
theClass.prototype = obj.instance || {};
// any any static variables or methods
if(obj.static){
for(var key in obj.static){
theClass[key] = obj.static[key];
}
}
return theClass;
}
If you’ve been following along with the entirety of this tutorial (including previous posts), you should be able to work out what each part of the above function does.
This ends the Javascript tutorials. Next time, I may go through the Javascript libraries that are available. Until then, keep coding.
Robert