Friday, January 23, 2015

JavaScript In Action

My professional life driving me to JavaScript & friends.
In JavasScript there are some tricks to define new objects so in this post I'm going to describe how to define an object\class and how to implement inheritance in JavaScript.

Namespace Organization

The thing is is a bit 'off topic but is required to obtain well organized code and objects.
Namespace is used for group and organize class, function and global objects.

This code example define the jsObjects namespace and jsObjects.WMS sub-namespace.
This is possible thanks to IIFE and singleton.
IIFE mean: "immediately invoked function expression".
IIFE is defined declaring an anonymous function wrapped in parenthesis and ended with open and closed parenthesis.
In this way the function is executed immediately after the file is loaded.

//namespace definition with IIFE and singleton
(function () {
    //jsObject definition and creation with singleton 
    this.jsObjects = this.jsObjects || {}; 
    var rootNamespace = this.jsObjects;
    //sub-namespace creation with singleton
    rootNamespace.WMS = rootNamespace.WMS || {}; 

   //place your classes here

}()); //IIFE



Using namespace we can use object in this way:

var pallet1 = new jsObjects.WMS.MyObject();


Base class definition


These are the steps to define a new class definition:
  1. Declare a variable and assign an IIFE to it.
  2. Surround a named function with previous IIFE. (This function will be constructor and class implementation).
  3. Declare your member inside previous constructor.
  4. Return the function name.
  5. Make class visible from namespace.
The example below define "Package" class and is exposed by jsObject.WMS namespace

    //package class definition
    var Package = (function () { 
        function Package(barcodeArg) { //this function is the constructor
            this.barcode = barcodeArg; //publicly accessible member
        }
        return Package; //return Package object definition
    })(); //IIFE

    //exposing class on jsObjects.WMS namespace
    rootNamespace.WMS.Package = Package;



Now we have to put this class inside the previously declarated namespace like this:


//namespace definition with IIFE and singleton
(function () {
    //jsObject definition and creation with singleton 
    this.jsObjects = this.jsObjects || {}; 
    var rootNamespace = this.jsObjects;
    //subnamespace creation with singleton
    rootNamespace.WMS = rootNamespace.WMS || {}; 

    //Package object definition
    var Package = (function () { 
        function Package(barcodeArg) { //this function is the constructor
            this.barcode = barcodeArg; //publicly accessible member
        }
        return Package; //return Package object definition
    })(); //IIFE

    //exposing class on jsObjects.WMS namespace
    rootNamespace.WMS.Package = Package;

}()); //IIFE





We can use Package object from jsObjects.WMS namespace in this way:


var pallet1 = new jsObjects.WMS.Pallet("PALLET1");


Derived class definition

These are the steps to define a Box object derived from Package object:

  1. Declare a variable and assign an IIFE to it ("Box").
    1. At the end of IIFE function pass the base class type (Package in this case).
  2. In the IIFE function clone "Package" class setting the prototype property of previously declared variable ("Box.prototype = new Package()");
  3. Change the constructor of Box prototype to use the Box's constructor.
  4. Implement the new Box Constructor.
  5. Inside Box constructor call base class's constructor (parent.call(this,...
    1. first argument of parent.call is "this". 
    2. the others are arguments needed by base class's constructor.
  6. Declare your member inside previous constructor.
  7. Return the function name.
  8. Make class visible from namespace.

    //inheritance definition (parent is Package like in IIFE at the end of this class)
    var Box = (function (parent) { 
        //assign to this class prototype the base class definition
        Box.prototype = new Package(); 
        //switch base class constructor with derived class constructor 
        Box.prototype.constructor = Box; 
        function Box(barcode) { //constructor
            parent.call(this, barcode); //calling base class constructor
            this.fragile = true; //added new public accessible member
        }
        return Box; //return Box object definition
    })(Package); //IIFE (pass Package definition to base class)

    //exposing class on jsObjects.WMS namespace
    rootNamespace.WMS.Box = Box;





We can use Box object from jsObjects.WMS namespace in this way:


var box1 = new jsObjects.WMS.Box('BOX1');


Public fields and inheritance

We can add a field publicly accessible using "this." keyword like barcode in the "Package" class example.

    //Package object definition
    var Package = (function () { 
        function Package(barcodeArg) { //this function is the constructor
            this.barcode = barcodeArg; //publicly accessible member
            var alternativeBarCode;
        }
    })(); //IIFE

In this way every one can access to barcode field.

Private fields and inheritance

We can add a field that is accessible only by the class that we are defining. This is a "private member". we accomplish this declaring a variable with "var" keyword.

For example we can add the private field"alternativeBarCode" to the Package Class like highlighted cod in the example below.

    //Package object definition
    var Package = (function () { 
        function Package(barcodeArg) { //this function is the constructor
            this.barcode = barcodeArg; //publicly accessible member
            var alternativeBarCode;
        }
    })(); //IIFE


In this way only "Package" class can access and modify "alternativeBarCode" member.
Inside public function we can use private member like example code below.

Public functions and inheritance

Public functions

We can declare public function using "this.myFunction = function".
Inside public function we can use private member like example code below.
Public function are automatically inherited and publicly exposed by derived class but derived class cannot override its behavior because this kind of function is not overridable.

You can see in the example below that "Box" object inherit from Package and "setAlternativeBarCode" function is called from "Box" instance.


    //Package object definition
    var Package = (function () { 
        function Package(barcodeArg) { //this function is the constructor
            this.barcode = barcodeArg; //publicly accessible member
            var alternativeBarCode;
            this.setAlternativeBarCode = function (alternative) {
                alternativeBarCode = alternative;
            }
            this.getAlternativeBarCode = function () {
                return alternativeBarCode;
            }
        }
    })(); //IIFE

    //inheritance definition (parent is Package like in IIFE at the end of this class)
    var Box = (function (parent) { 
        //assign to this class prototype the base class definition
        Box.prototype = new Package(); 
        //switch base class constructor with derived class constructor
        Box.prototype.constructor = Box;  
        function Box(barcode) { //constructor
            parent.call(this, barcode); //calling base class constructor
            this.fragile = true; //added new public accessible member
        }
        return Box; //return Box object definition
    })(Package); //IIFE (pass Package definition to base class)


Somewhere in your code you can use base class method in this way:

    var box1 = new jsObjects.WMS.Box('BOX1');
    box1.setAlternativeBarCode("BOX-K1");

Function prototype and inheritance

Prototyping is one of the most important thing of JavaScript (but this is another story).
In this post I'm writing only about function prototype regard inheritance.

Using function prototype is possible to implement a function in base class and to redefine its behavior in derived class.

Function prototype is typically locate outside constructor function and inside IIFE of class definition like example below.
The syntax is: [ClassName].prototype.[functionName] = function(....


    //Package object definition
    var Package = (function () { 
        function Package(barcodeArg) { //this function is the constructor
            this.weight = 0; //publicly accessible member
            this.height = 0;//publicly accessible member
            this.width = 0;//publicly accessible member
            this.depth = 0;//publicly accessible member
            this.barcode = barcodeArg; //publicly accessible member
            var alternativeBarCode;
            this.setAlternativeBarCode = function (alternative) {
                alternativeBarCode = alternative;
            }
            this.getAlternativeBarCode = function () {
                return alternativeBarCode;
            }
        }
        //prototype function is inherited automatically and is possible to 
        //redefine the same method in derived class and override behavior
        Package.prototype.getInfo = function () { 
            return ' barcode:' + this.barcode + ' weight: ' + this.weight + 
                   ' height:' + this.height + ' width:' + this.width + 
                   ' depth:' + this.depth + 
                   ' alternative:' + this.getAlternativeBarCode();
        }
        return Package; //return Package object definition
    })(); //IIFE



Given that is placed outside constructor, prototype function "getInfo" cannot access to private field like "alternativeBarCode". So if you need to access some field you can create public function like "getAlternativeBarCode" and use it.

We have "getInfo" prototype function in Package object so in derived class we can overwrite its behavior and call base class's implementation.


    //inheritance definition (parent is Package like in IIFE at the end of this class)
    var Pallet = (function (parent) {
        //assign to this class prototype the base class definition
        Pallet.prototype = new Package();
        //switch base class constructor with derived class constructor 
        Pallet.prototype.constructor = Pallet; 
        function Pallet(barcode) { //constructor
            parent.call(this, barcode); //calling base class constructor
            this.thickness = 0; //add new public accessible member
        }
        //This prototype override base class's getInfo function
        Pallet.prototype.getInfo = function () {
            //call to base class implementation of getInfo function
            return parent.prototype.getInfo.call(this)
                //change behavior to base class implementation
                + ' thickness:' + this.thickness; 
        }
        return Pallet; //return Pallet object definition
    })(Package); //IIFE (pass Package definition to base class)



To accomplish this we can define prototype function "getInfo" in "Pallet" object; inside the new "getInfo" function we can call base class implementation using this syntax:
parent.prototype.[functionName].call(this,[function arguments]);






Somewhere in your code you can use base class method in this way:

    var box1 = new jsObjects.WMS.Box('BOX1');
    var info = box1.getInfo();