Sunday, November 2, 2014

Implement inheritance in JavaScript

Introduction

I have implemented Object-Oriented concepts in JavaScript, want to share with you my experience. As we know that there's no keyword like "class",  "extends", "implements" etc. in JavaScript. But  still we can achieve up to some extent. JavaScript function are first-class-objects which can store logic and data, and we are going to implement classes using JavaScript functions.

I have used __proto__ property for inheritance, this is the standard property according to ECMAScript 6.
Please find more information about __proto__  here.
https://people.mozilla.org/~jorendorff/es6-draft.html

Code

We are going to create two classes, Employee and Manager, Manager class inherit all the properties of  Employee class.  Let's see the code

Employee = function(id, name, age){
    this.empId = id;
    this.name = name; 
    this.age = age;
    alert('A Employee is created.');
}


// Let's add two methods in Employee class, Even it is not  relevant but we are adding just to achieve inheritance. Note, please do not override prototype object, just add in new methods in that object. Another way you won't get recognize the class name in debugger.

Employee.prototype.getName =  function() { return this.name; };
Employee.prototype.getAge =  function() { return this.age; };


Before moving further we need to define our extend function which we are going to use for inheritance. As all JavaScript programmer know that we have to do special handling for IE, we did the same here.
extend = function (subClass, baseClass) {
     if (navigator.appVersion.indexOf("MSIE") == -1) {
         // it gives the clear picture of object hierarchy during debugging, but this code runs only on Firefox and chrome.
         subClass.prototype.__proto__ = baseClass.prototype;
     }
     else {
         // special handing for IE 9/10 etc.
         function inheritance() { }
         inheritance.prototype = baseClass.prototype;
         subClass.prototype = new inheritance();
         // store constructor as it is
         subClass.prototype.constructor = subClass;
     }
};

Now, we are going to define Manager class 

Manager = function(empId, name, age, resources) {
    Employee.call(this, empId, name, age);
    this.resources= resources;  // no. of resources managed by Manager
    alert('A manager has been created.');
}
First extend all the properties of base class and then defines for current class
extend(Manager, Employee);

Manager.prototype.getResources= function() {
    // This alert shows that we can access all members of base class and sub class
    // alert('I am ' + this.name + " and managing " + this.resources + " resources");
    return this.resources;
}

Please find clear picture of inheritance in debugger



It is time to see the result of the above code, let's create object of Manager class and access all the properties and functions

var manager = new Manager(1, 'Anurag Singh', 30, '7');

Get the employee Id of manager, this is defined in Employee class

alert(manager.empId);  

Get the age of manager, this function is defined in Employee class

alert(manager.getAge())

Now, get the no. of resources manages by manager

alert('I am ' + manager.getName() + " and managing " + manager.getResources() + " resources");


This the simple way we may achieve object-oriented approach in JavaScript.
Please note that functions we defined in individual class may not relevant, we used here for explanation only.

Implement namespace in JavaScript

Introduction

JavaScript doesn't provide any language feature for creating and managing modules. Namespace is very important concept to prevent collisions. 

Namespace is very important specially when you are writing open source module or public APIs, There's lot of possibility that two modules define global properties with the same name, and module overrides the properties of another and one or both module do not work as expected.

Code

Lets do some hands-on, we may create simple namespace like this

var myModule = {};

myModule.func1 = function() {
 // code goes here
}

But there could be possibility that any one define the same name for his/her modoule. Huh..:(

I would suggest we should follow the same convention as we do in other programming languages like Java and C#

var com = {};
com.companyName= {};
com.companyName.projectName= {};

Okay.. Looks fine. but what will happen if you include another JavaScript file which already define "com" namespace and some properties. Boom!!!. We already overwrites all the properties define under "com", which we really do not want. Let's avoid overriding the "com" namespace.

var com = com || {};
com.companyName= {};
com.companyName.projectName= {};

Still we are not in safe position, I am giving time to you think about it.

Any Idea? :)

Hmm. I hope you already got the clue and reached there. Yes, you are absolutely right. If we include two different libraries from the same company then we may override other libraries properties because it is also defines in the same namespace "companyName",

var com = com || {};
var com.companyName =  com.companyName || {};
var com.companyName.projectName = {};

Hmm. You might be thinking about check for "projectName" too. Don't worry, we are safe here for project name because two project with same name shouldn't run in the same company. If two projects are running with same name but definitely they won't be release in public domain. But Just to be on safe side, adding check for "projectName" won't create any problem in code. Please add it.

Now we are ready to add our new function in our module.

com.companyName.projectName.myFucntion = function() {
      // code goes here
}

So far so good, Let's wrap into a handy function so that anyone can use it.

function createNamespace(companyName, projectName) {
    var namespace = com;
    // project may define in some other script file
namespace[companyName] = namespace[companyName] || {};
    return namespace[companyName][projectName] = {};
};

This is the right way to use without overriding com object. Please define com object in your script and make sure check if it is exist or not.

var com = com || {};

var serachEngine = createNamespace("Google", "SearchEngine");

Now, it is easy to define your function

searchEngine.search = function() {
      // code goes here
}

Hope it will help you to organize your project in multiple files.

Thanks for your time, Please leave your comment for improvements.