Oriented-Programming with JavaScript

Small Talks

When I started programming with JavaScript, knowing languages such as C++ or Java, I found it kind a messy. Only function, no class, no real structure (only Arrays and Object), and back to those years, using this loosely typed language was like walking on eggs. Now, frameworks such as JQuery, Mootools or Dojo, have highly simplified JavaScript development, in their relative field. New structures are added, to mimic strongly typed languages, such as Maps, LinkedList or whatever. Some libraries provide an inheritance feature, aimed at structuring the code. Client-side app becoming heavier and heavier, bringing OO patterns in JS can be very useful for big app development and maintenance.

Over the internet, it seems there are many ways to accomplish OO feature in JavaScript, such as Classical Inheritance, Swiss Inheritance, Parasitic Inheritance, and maybe more. Some are property-copying based, others use the prototype property or even combine those methods. I encourage you to read about that to understand the underlying concepts in JavaScript. Even if you embrace one of those methods, you still need to develop the sugar around to be able to mimic parent class method call, or inheritance chaining among classes. Another solution would be to directly add an external library and use the OO feature through it. But what if you don’t need to add a whole big library to use two features? What if you feel like it’s a waste of resources?

A Solution: xbObject

I’m going to show you how to use a small piece of code that does the magic and solves many problems in JavaScript OOP: inheritance, parent method call, etc. without a headache about JavaScript prototype theory. At the end, I will expose its weaknesses too. The strong value of this is that you don’t need a full library to use one feature, it’s simpler, it doesn’t interfere with other piece of code, and you can use your model anywhere. It weighs about 7Kb unpacked, and 2Kb minified (if you use gzip, you can even go to 700 bytes!).

We are going to use xbObject.js, written by Bob Clary. You can have the code here. Let’s deep into some OO concepts, beginning by Class and Instantiation.

Class and Instance

Let’s define a class “Company” as :

To instantiate it, and invoke a method, just do as follow :

Which should output :

If you inspect the company object, with firebug for instance, you will see that you can access the attributes “name” and “size” from the outside. This unfortunately breaks the encapsulation concept of OOP. A lot can be done to mimic this feature, there are two articles that I find great to explain how to achieve that here, and here. We won’t discuss this, because first, this topic has a lot to do with efficiency and some problems can arise, and second, I don’t think this is very useful here considering our code is readable by anybody. If you want to “encapsulate”, just take a naming convention and explain it in your API.

Inheritance

Let’s define “Intelytics”, a company, inheriting from “Company” :

The following code :

Will output this :

Here we have introduced two principles. The inheritance, and the parent method call. You inherit from a class by using the second parameter of the _classes.registerClass method (l. 2). On line 15, you are given an exemple of parent method calling, through the this.parentMethod call. The first parameter is the method name to call. To pass arguments, just list them, the method will handle multiple arguments alone. Note that you can directly call this.method to call a parent method. It will work too, but parentMethod will be of help when talking about overloading and overriding.

Now you are saying “Wait a sec … Output lines 1 and 2 are the same ! What’s happening here ?”. Actually, when you instantiate a class inheriting from another one, the “framework” instantiates a parent class for chaining purposes. To avoid useless computing while instantiating a class, use this trick in the Company class contructor :

Now, the output will look like this :

Multi-inheritance is possible, by calling the registerClass multiple time like this :

But, unfortunately, you’ll have to handle collisions yourself. If you are in that case, you might want to look into the Swiss inheritance.

 Overloading and Overriding

Well, I call here overloading the possibility, within the same class, to create two, or more, functions with the same name and different arguments. I call overriding the process of declaring a function with a name that matches a parent class function name, regardless of the arguments. Why being so uselessly specific here ?

Because overloading is not possible here. If you try the following code, only the last defined method will be called :

The output :

If you want to achieve overloading by all mean, a way could be to do like the following code suggests. But I wonder if it’s really worth the pain :

It will output :

The trick here is to use the arguments variable of the function, containing all arguments passed. But we have to do all the job here, analyzing the number and type of arguments passed to choose the good function to call.

The overriding is possible though. You can easily redefine a method in the subclasses and call it, the parent method remaining callable :

Output :

 Abstract Methods

Here is a concept really cool of OOP, that allows us to undertake useful patterns. Let’s see if it’s feasible. Let’s be crazy and define three classes :

And, the output will fortunately be :

Outch, it’s working !

Consequences

If chosen, this method has a great asset : you can make strong app architectures without depending on a big library you need only for one feature ! That leads to make reusable components you can use in multiple projects.

Some drawbacks though:

  • The parentMethod is supporting only ten arguments. That’s ok, regarding the fact that you rarely pass more than five arguments, but, hey, a quick look into the xbObject code and you can make it infinite with the arguments variable of JS function (see line 198 in xbObject.js). Another trick is to directly pass objects containing parameters, just like popular frameworks do.
  • Encapsulation is not really achievable without severe drawbacks (arguable depending on the project though)
  • Can we inherit from JavaScript current objects such as Array or even DOM elements ? :)
  • If you want to make components, or make “modules” (such as putting one class per JS file), that means you will include all those classes one by one in the correct order in the final page to use a component!

If you want to go along the last point, you should take a look on connexity algorithms first, and cope with automated packaging too. This is a really interesting part in JS project packaging. A post on that topic might follow ;)

 

If you like what you read, share!

Leave a Reply

Your email address will not be published. Required fields are marked *

*

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>