Tuesday, March 31, 2009

JavaScript Classes

Most people hate JavaScript and for that reason copy snippets here and there without thinking about how to make it more object-oriented and encapsulated like they do in their other languages. I have found these 4 ways to make javascript classes, which gives them scope and control over what is exposed. It also reduces the chance that your page has a function getName() and so does that .js file you are including! (BTW, the last one interpreted by the browser wins.)

Here is code for 4 different ways to do it, with each outcome below it. My preferred way is Three.


var One = {
me: "me",
myself: "myself",
i: function() {
return 1;
}
};

One cannot be constructed, all fields are public static.

equals( "me", One.me );
equals( "myself", One.myself );
equals( 1, One.i() );

------------

var Two = function() {
var me = "me";
this.myself ="myself";
this.i = function() {
return 1;
}
};

Two must be instantiated. Fields declared with 'var' are private, those declared with 'this.' are public.

var twoInst = new Two();
equals ( undefined, twoInst.me ); //because it is private
equals ( "myself", twoInst.myself );
equals ( 1, twoInst.i() );

------------

var Three = new function() {
var me = "me";
this.myself ="myself";
this.i = function() {
return 1;
};
};

*Three is my preferred way. Three is a singleton (already instantiated), fields may be private or public, called like a static. Fields declared with 'var' are private, those declared with 'this.' are public.

equals ( undefined, Three.me ); // because it is private
equals ( "myself", Three.myself );
equals ( 1, Three.i() );

------------

function Four() {
var me = "me";
this.myself = "myself";
}

Four.prototype.getMe = function() {
return this.me;
}

Four.prototype.getMyself = function() {
return this.myself;
}

Four.prototype.i = function() {
return 1;
}

Four must be instantiated, but the class is open and you can continue to add fields to it. Every instance gets every prototype of that class the window knows about.

var fourInst = new Four();
equals( undefined, fourInst.me ); // because it is private
equals( "myself", fourInst.myself );
equals( undefined, fourInst.getMe() ); // because it is private
equals( "myself", fourInst.getMyself() );
equals( 1, fourInst.i() );

No comments:

Post a Comment