2010-11-16

Some Classes in JavaScript

I did some client-side coding using MooTools. There, as a long-time Java developer, I liked the way I could define classes like in some more object oriented languages:


var Vehicle = new Class({
drive : function() {
console.log("I'm driving a " + this + " with a top speed of " + this.topSpeed);
},
});
var Car = new Class({
Extends : Vehicle,

topSpeed : 250,

initialize : function(make, model) {
this.make = make;
this.model = model;
},

toString : function() {
return this.make + " " + this.model;
},
});
new Car("Fjord", "Taunus").drive();


Then I went on to server-side JavaScript, namely on node.js. There I immediately felt a bit weak without the Class() constructor. I did some googling to see if I could have Mootools on server-side too, but got under the impression that it's not that easy, requiring some customization of Mootools. Hence, I decided to roll my own. And here it is:



function Class(props) {
function copyProperties(from, to) {
for (var key in from) {
to[key] = from[key];
}
}
var constructor = function() {
props.initialize.apply(this, arguments);
};
if (props.Extends) {
copyProperties(props.Extends.prototype, constructor.prototype);
}
copyProperties(props, constructor.prototype);
return constructor;
}



That's not so much code after all, is it? The code in the first snippet actually works with my Class constructor. As you can see, it supports subclassing using 'Extends', a constructor named 'initialize' and any number of methods and properties.


It took me a couple of hours to get these roughly 10 lines of code together though. I had to realise that


  1. The "class" is actually a constructor function. Hence,  the Class() function has to return a constructor
  2. In any Javascript function, you have an "arguments" array (well not stricly an array but..) that you can use to access all arguments
  3. You can call any Function using its apply function with the "this" object and a list of arguments
  4. You can easily copy properties of an object by looping them using "for key in object"
I have to admit that I'm still a bit confused how this all works though :)

Feel free to prove my über-simple class system wrong and point me back to the correct path.

2 comments:

  1. Your point about the Observer pattern decoupling events but not solving the underlying mutable state problem is so insightful. That's why functional reactive programming with composable signals (Properties and EventStreams in Bacon.js) is such a game-changer. As a working developer balancing legacy maintenance with modern skill growth, I appreciate how these architectural lessons apply across languages. The same principles of reactive streams exist in Java with Project Reactor and RxJava. To stay current while working full-time, I joined a real time java training in electronic city Bangalore that offers weekend batches and covers reactive programming paradigms. Thanks for this deep dive—I'm now inspired to revisit Bacon.js and apply its lessons to my current projects. When can we expect Part II?

    ReplyDelete