OOP in JavaScript - Part 1: Writing classes

Permanent Link: OOP in JavaScript - Part 1: Writing classes 12. September 2009 RSS Feed for comments on RSS-Feed für Kommentare zu: OOP in JavaScript - Part 1: Writing classes comments feed

OOP in JavaScript works a bit different than known from other languages. That's why I decided to do a series of "OOP in JavaScript" blogposts, where I want to show how OOP in JavaScript works. The series will discuss topics like creating classes, prototyping, extending classes, static classes, scoping, and so on. To understand these postings a basic knowledge of JavaScript and OOP is needed. This first part is about creating classes/prototyping.

First thing you need to know: There is now keyword class in JavaScript. In order to create a class in JavaScript, all you have to do is to create a function and then create a new class instance by using the known keyword new:

function Product() {}

var product = new Product();

The function we've created is the constructor of our new class. To create methods and properties there are two ways: You can either declare them in the constructor or you can do prototyping.

Declaring it in the constructor:

function Product() {
this.id = 71288;

this.getId = function() {
return this.id;
}
}

Prototyping:

function Product() {}

Product.prototype.id = 71288;

Product.prototype.getId = function() {
return this.id;
}

Personally I prefer prototyping as it is more clear. If you want to call the function getId() it always works the same way with both methods:

var product = new Product();
alert(product.getId());

This class is still quite static, since the id is hardcoded in it. To make it dynamic I just need to modify the constructor to make it accept a config object. Notice that I replaced the id property with a config property that stores the whole config given to the object.

function Product(config) {
this.parseConfig(config);
}

Product.prototype.config = {};

Product.prototype.parseConfig = function(config) {
if (typeof config != 'object') {
throw('Parameter "config" must be of type object');
}
// ID should always be set and a number
if (typeof config.id != 'number') {
throw('Config Parameter config.id must be a number');
}
this.config = config;
}

Product.prototype.getId = function() {
return this.config.id;
}

As you can see I also already implemented checks that the config must always be an object and that an id must always be set and a number. Creating a new instance of the class now looks like this:

var product = new Product({
id: 71288
});

This way we can now dynamically create Product Objects based on Product IDs we read from e.g. a database.

In the second part, that will come within the next few days I will write about static classes.

4 comments

Pauls Gravatar

Paul
14.09.2009, 04:52 o'clock

Thanks for a much-needed blog topic! What do you think about declaring static classes with "new function" and using "var" for privates, "this" for publics? I like this approach so far on my project because encapsulating all the methods and attributes together inside a class declaration is most like java and thus familiar for my team. I have blogged about it here (see approach Three): http://paulmazak.blogspot.com/2009/03/javascript-classes.html
I'm curious if you still prefer prototyping after considering other ways to create OOP Javascript.

Dominik Jungowskis Gravatar

Dominik Jungowski
14.09.2009, 14:14 o'clock

Declaring static class with new: One could do that, I just don't see a benefit unless you do what you and I've done in the following passage.

Using var for privates seems like a nice idea at first, but it's rather a "superprivate" since you only have the var in the scope of the concurrent function (like always in javascript) which makes it rather useless unless you declare the methods in the constructor otherwise none of your methods can use it:

function Registry()
{
var somestuff = '123abc';

this.get = function() {
return somestuff;
}
}

var reg = new Registry();
alert(reg.get());

Vlad Dumitricas Gravatar

Vlad Dumitrica
15.09.2009, 12:54 o'clock

I think will be a n interesting series of articles.

I'd rather go with encapsulation, so I prefer something like this (a variant of Paul's "Three" version):
Test = function(){
var privateData = {
appVersion: '0.1 alpha'
};

var publicData = {
getVersion: function(){
return (privateData.appVersion);
}
};

return publicData;
}();

Marcus Bs Gravatar

Marcus B
15.09.2009, 16:09 o'clock

The Bindows framework (http://www.bindows.net) is one of the most complete Ajax frameworks, and it uses prototype-based OOP throughout. There is a short introduction to JavaScript OOP in the Bindows user's manual (http://www.bindows.net/documentation/download/bindows_manual.pdf) p. 18 and onwards. It shows nicely how prototype-based OOP is flexible enough to accommodate a model that looks sufficiently close to class-based OOP that programmers with, say, a Java background can feel comfortable.

The Bindows model does not use encapsulation, instead relying on conventions for property accessors and public/private members.

Write a comment

(will not be published)