Javascript part one: « very object oriented »

Find back articles from this serie...
1/ Javascript part one: "very object oriented"
2/ Javascript part two: "very package oriented"
2/ Javascript part three: "very component oriented"

First thing I do when I start a javascript project is to set Classes.

 

JS is a Class-less language by default, bad bad bad.

You can still simulate a weird concept of Class with some tricks like this :

 

[cc lang= »javascript »]// A car « class »
function Car( model ) {
this.model = model;
this.color = « silver »;
this.year = « 2012 »;
this.getInfo = function () {
return this.model +  »  » + this.year;
};
}[/cc]

 

But if you come from the object-oriented-languages world (Java, C++ or even PHP5) you will quickly feel frustrations. Troubles come from javascript and its way of merging function and variable by forgetting the simple thing that is ‘type’!

 

And you will feel even more frustrated when you would like to do something you have always done… inheritance. There is no way to natively do it strictly.

 

And that’s it! 🙁

 

I think the most complicated thing to understand from javascript is the « no-rules » rule. You have to create your own pattern to manage your objects. This is linked to the concept of « Metadata Model » which create the model… okay, let’s simplify();

 

I would like to present what I think is the best javascript oriented object pattern from John Resig which support the needed features for a object js model:

 

[cc lang= »javascript »]// 1. You can do your mother class
var Car = Class.extend({
init: function(model) {
this.model = model;
this.color = « silver »;
this.year = « 2012 »;
},
getInfo: function() {
return this.model +  »  » + this.year;
}
});
// and finally have a real constructor!

// 2. You can do your inheritance
var Peugeot = Car.extend({
init: function() {
this._super( « Peugeot » );
this._origin = ‘French’;
},
getInfo: function() {
return this._origin+this._super();
},
origin: function(_) {
if( arguments ) return this._origin;
this._origin = _;
return this;
}
});
// You can even call the mother’s function 🙂

// 3. You can test object’s classes (the greatest thing)
var car1 = new Peugeot();
var car2 = new Car(‘Ferrari’);

if( typeof(car2) == ‘Car’ && car1 instanceof Peugeot
&& car1 instanceof Car && car1 instanceof Class ) {
return ‘what a good pattern’;
}
// the thing which most of design patterns for javascript doesn’t support..
// … just test the intermediate Class of objects

// 4. And for attentive people we could notice another pattern..
// – to set origin:
car1.origin(‘Deutschland’);
// – to get origin:
car1.origin();[/cc]

 

How is it possible ? It’s just a small file Class.js to ALWAYS INCLUDE in your javascript project. This is a high level definition of this javascript « very object oriented » pattern.

 

No need to get all this code, just use it!

 

[cc lang= »javascript »]
/* Simple JavaScript Inheritance
By John Resig http://ejohn.org/ MIT Licensed. */
// Inspired by base2 and Prototype
(function(){
var initializing = false,
fnTest = /xyz/.test(function(){xyz;}) ? /\b_super\b/ : /.*/;
// The base Class implementation (does nothing)
this.Class = function(){};

// Create a new Class that inherits from this class
Class.extend = function(prop) {
var _super = this.prototype;

// Instantiate a base class (but only create the instance,
// don’t run the init constructor)
initializing = true;
var prototype = new this();
initializing = false;

// Copy the properties over onto the new prototype
for (var name in prop) {
// Check if we’re overwriting an existing function
prototype[name] = typeof prop[name] == « function » &&
typeof _super[name] == « function » && fnTest.test(prop[name]) ?
(function(name, fn){
return function() {
var tmp = this._super;

// Add a new ._super() method that is the same method
// but on the super-class
this._super = _super[name];

// The method only need to be bound temporarily, so we
// remove it when we’re done executing
var ret = fn.apply(this, arguments);
this._super = tmp;

return ret;
};
})(name, prop[name]) :
prop[name];
}

// The dummy class constructor
function Class() {
// All construction is actually done in the init method
if ( !initializing && this.init )
this.init.apply(this, arguments);
}

// Populate our constructed prototype object
Class.prototype = prototype;

// Enforce the constructor to be what we expect
Class.prototype.constructor = Class;

// And make this class extendable
Class.extend = arguments.callee;

return Class;
};
})();
[/cc]

Powerfulness of javascript by a small piece of code which simplifies everything: file Class.js

 

Let’s design fun UML for javascript now!