Home > Web > Object Oriented Programming in JavaScript

Object Oriented Programming in JavaScript


“JavaScript is one of the most misunderstood programming languages”.
Do you agree on this? Personally, I partially agree. And I outline PARTIALLY.
I agree that the language allows you to do a lot of stupid things and that’s the case with most of the weak typed languages. On the other side, strong typed programming languages like Java or C#, stops you from doing some of the mistakes at compile time and saves you from a lot of headaches later.
But why I said partially? Because if you instruct yourself to work in some structured way, even JavaScript can be less painful. In this article I will tell you how to do this and I will cover how to implement the major OOP(Object Oriented Programming) principles in JavaScript.

Today’s systems problem becomes more and more maintainability and not performance. More and more features are requested by users and the computing power becomes more and more cheaper and widely available. And then a good software system architecture is the key. Object Orientated Programming augmented with Design Patterns comes with good solutions to these problems.

OK, but what this has to do with JavaScript? JavaScript is actually an OOP programming language, except that has a different paradigm then the other traditional programming languages. If C++, Java or C# are class-based OOP languages, JavaScript is prototype based.
Before diving deep into JavaScript OOP, let me give you a little bit of background about JavaScript itself. Even tough you know the language pretty well you should still read this, as it will help you in a deeper understanding.

Basically, everything in JavaScript is an object. And every object has a map of properties associated, from where you can get (object[propertyName]) or set (object[propertyName] = propertyValue) a property. If the property name can be only a string (if another type is passed the toString method is called first), the property value can be anything: objects, numbers, strings and even functions.
With that in mind let’s get back to OOP. Supposing that you are used with a class-based paradigm, I would make a parallel between the two.
Let’s see first how to define a class.

function MyClass() {
}

You haven’t defined only a function, but a class as well. You can create new objects using var obj = new MyClass();. So you also have the constructor. But this is the no-arg constructor. How can you define a constructor that accepts arguments. Just add some arguments to the function. If you don’t specify them, they will be passed as null. And you have the overloading too.

function MyClass(name) {
    this.name = (name != null ? name : "Default");
}

You already saw the this keyword. It is a reserved word and refers to the function scope, which in the case of creation of new objects is the object itself. And name is a class field. JavaScript class fields can be accessed only using this.propertyName, which is practically an equivalent form of this[propertyName]. The this prefix is not implied, but mandatory.
Now let’s define some class methods. When doing this you have a few options. I’ll present them to you and tell you the advantages and disadvantages and what is my recommendation.

  1. function MyClass(name) {
        this.name = (name != null ? name : "Default");
        this.doIt = function() {
            // do something
        };
    }
    
  2. function MyClass(name) {
        this.name = (name != null ? name : "Default");
        this.doIt = MyClass_doIt;
    }
    
    function MyClass_doIt {
        // do something
    }
    
  3. function MyClass(name) {
        this.name = (name != null ? name : "Default");
    }
    
    MyClass.prototype.doIt = function() {
        // do something
    };
    

In the first version doIt is defined as a method. When the constructor is called, a new function is created and the value of the doIt property is assigned to it. From a syntactical point of view this looks very much alike to Java or C# and you probably like it, but that’s far from optimal. Because the function will be defined for each and every object of the class.
The second version overcomes this problem. The function MyClass_doIt is defined only once and in the constructor is only referenced.
But there is even a better way(3), but we have to discuss first about prototype.

I was saying above that every object has a set of properties. If you try to access a property or a method that it is not defined for that particular object, then the next step taken by the JavaScript engine is to look in its prototype. If still not found, then the prototype of the prototype will be inspected and so on. The prototype hierarchy is similar to the class hierarchy from Java or C#. If you want you can look at the prototype as an object common to all the objects of the same type. If you modify a prototype property this will be reflected in all the objects with the same prototype. If you define a function as a type, all the object created with the new operator will have the same prototype, the function prototype itself.

In this light, the third version becomes self explanatory: define the class methods in the prototype directly, so all the existing and future objects can benefit of them.
If you add or modify a method to a prototype, not only that all the future objects will benefit of it, but also all the already created objects. This concept of dynamically modifying a type could be new if you come from the Java or C# world.

And now let’s discuss about inheritance, probably the hardest part of OOP in JavaScript. Inheritance in JavaScript is not implemented as easy as other traditional OO languages. This is not simply marking as being part of an hierarchy, but having the same prototype.

Let’s extend MyClass with MyExtendedClass.

function MyExtendedClass() {
}

MyExtendedClass.prototype = new MyClass();
MyExtendedClass.prototype.constructor = MyExtendedClass;

The line MyExtendedClass.prototype = new MyClass(); links the prototype of the prototype of MyExtendedClass to MyClass, simulating the inheritance. The line after just sets the correct constructor of MyExtendedClass objects, otherwise set to MyClass.

Along with inheritance comes the super concept and overriding. If you define a method in the extended class prototype you simply override from the base class prototype (it will be found there first). There is a way to call the super constructor and methods:

function MyExtendedClass() {
    MyClass.call(this); // call the super constructor
}

MyExtendedClass.prototype = new MyClass();
MyExtendedClass.prototype.constructor = MyExtendedClass;

MyExtendedClass.prototype.doIt = function() {
    MyClass.prototype.doIt.call(this); // call the super method
};

Actually this way you can call any method in the hierarchy.

If we touched inheritance, then polymorphism comes naturally on the way. And if we think that objects in JavaScript don’t have a reference type, but only the actual type, then this is automatically implied.

We have to do one more stop: encapsulation. The solution here is a little bit more tricky. I will show you how to define a private field an accessor methods for it.

function JustAClass() {
    var privateField = 10;

    this.getField = function() {
        return privateField;
    }

    this.setField = function(value) {
        privateField = value;
    }
}

So, the solution here is to define a local variable. The context (and the variable in this context) will be accessible in the methods (as they are in the same context), but not outside. Personally I don’t like this method as this relies on the first way of defining methods.

The major OOP principles are abstraction, encapsulation, inheritance and polymorphism. In this article I touched how you can implement all these principles. Abstraction comes with design and you have to use composition. You saw how to define fields and methods for a class. Encapsulation is basically about making the data private and I described how to implement it. Inheritance is about having a common prototype.

Just to make it easier, you should keep in mind that an object in JavaScript is a collection of properties (and even methods can be considered properties). And a property is first looked upon in the object and if not found in the object’s prototype, and then in the prototype’s prototype and so on.

I always said that if you want to take an interview to a JavaScript developer, the best way will be to ask him to create an hierarchy of two or more classes and discuss the pitfalls. Learning a framework, some method signatures, some object documentation, this comes with time and exercise, but knowing all these internals must be crystal clear from the beginning if you want to develop complex systems in JavaScript.

Categories: Web Tags: ,
  1. No comments yet.
  1. May 11, 2009 at 8:35 am

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: