Showing posts with label OOJS. Show all posts
Showing posts with label OOJS. Show all posts

Wednesday, April 16, 2014

JavaScript for Application: OO and Best Practices

So, here are some of our best javascript practices:

1) Almost always scope your JS code "immediate function"

JavaScript does not have code block scoping (with { ... }) but everything in a function is scoped. Consequently, when building a new module, always create an immediate function to scope all the properties and functions. This way, you can expose the public properties and methods/object types you want, and keep the rest visible only to this function body (this is very convenient for scoping).


// create the mymodule object if it does not already exists
// Note: this is global scope since it is outside of the immediate function   
var mymodule = mymodule || {}; 
//immediate function notation(start with ";" to make it semicolumn-less friendly)
;(function(){ 
// obviously, always have "var ..." when defining a variable (always) 
var foo; 
// nobody outside can see this var 
function bar(); 
// this will be visible outside, since attached to mymodule. 
mymodule.publicFun1 = function() {...};  })(); 
// execute the function immediately 


Partition your code diligently with this technic to ease later refactoring. Do not hesitate to have multiple "immediate function block" in the same javascript file, the more atomic your code is, the more manageable it will become. Use clear commenting style to separate your different sections.

2) Object Type the JS Way with prototype

Here is the prototype way to create an Object Type. 


// try to always scope your API, Object Types, properties in a namespace  
var mymodule = mymodule || {};;(function(){// Constructorfunction Person(name){this._name = name; 
// as convention, ._*** is for privates properties
// Note: there is a more robust way to do do private, but this will be for later
}
// A ObjectType Method
Person.prototype.name = function(name){
// Note: here, we use the js/jQuery style, setter/getter in one method
if (typeof name === "undefined"){
return this._name ;
}else{
this._name = name;
}}
// expose the Person "Object Type" in the mymodule namespace mymodule.Person = Person;})();
// ... somewhere else in your js or page code
// create an instance of this Object Type
var person1 = new mymodule.Person("Animesh");
// get some properties
console.log("person name: " + person1.name());
// >>> will output >>> "Animesh"


3) "Classical" Inheritance in JS

Here are 5 lines of code that you can add to your application, or use from some librairies (e.g., YUI, Brite, ...) to do a pseudo class inheritance with JavaScript. This is a very simple and convenient way to bring "classical" inheritance in JS.

function inherit(Child, Parent) { 
 var F = function() {}; 
   F.prototype = Parent.prototype; 
   Child.prototype = new F(); 
   Child._super = Parent.prototype; 
   Child.prototype.constructor = Child;
 }; 
 var mymodule = mymodule || {}; 
 ;(function() { 
   function Person(name) { 
    this._name = name; 
 }

 Person.prototype.name = function(name) { 
  if( typeof name === "undefined") { return this._name; } 
  else { this._name = name; } 
 } 

 Person.prototype.canCode = function(canCode) { 
  if( typeof canCode === "undefined") { 
    return this._canCode || false; 
  } else { 
    this._canCode = canCode; 
  } 
 } 

 function Programmer(name,language) {
  Programmer._super.constructor.call(this, name);         this.canCode(true); this.language(language); 
 } 
 // inherit Programmer with Person, call this after the Programmer constructor 

 inherit(Programmer, Person); 
 Programmer.prototype.language = function(language) { 
 // sort version of the if/else 
 return (typeof language === "undefined")? this._language:this._language = language; 
} 

// Note: Here you could override or overwrite person methods with // Programmer.prototype.**** 

mymodule.Person = Person; mymodule.Programmer = Programmer; })(); // in the application code 
var a = new mymodule.Person("Animesh");
var b = new mymodule.Programmer("Nanda","js");
console.log(a.constructor.name + " " + a.name() + " can code: " + a.canCode());
console.log(b.constructor.name + " " + b.name() + " can code: " + b.canCode() + " language: " + b.language());



4) Private Methods

The immediate function code block and the javascript function methods function.call and function.apply are perfect to create private methods. Immediate function code block is also a great way to make utility functions, constants, default values, and cache visible only to a module or sub module.



var mymodule = mymodule || {}; ;(function(){ 

// --------- Public API --------- //
// Constructor 

function Chart(){ }
Chart.prototype.refresh = function(data){ 
  this._data = data;
  // we call the draw with the "this" context 
  draw.call(this); 

// note: could use, "draw.apply(this,arguments)" if we wanted to pass all arguments 

}   

// --------- /Public API --------- //
// --------- Privates --------- //
// only this function block can see the draw method 

function draw(){ 

 // ... some code that will draw
 // call the utilities functions

 console.log("drawing data: " + this._data); } 

 // --------- /Privates --------- // 
 // --------- Utility Functions & Values --------- // 

 var color = {line:"#333",text:"#358"}; 
 function drawGrid(args)  { 
  // .... 
 } 

// --------- /Utility Functions & Values --------- // 

mymodule.Chart = Chart;})(); 

// somewhere in the code 


var chart = new mymodule.Chart();chart.refresh(["name1",345,"name2",654]); 

// >>> will output >>> drawing data: name1,345,name2,654





With Regards,
Animesh Nanda
Sr.Software Engineer | Photon Infotech
Bengaluru | Karnataka | INDIA.

Monday, April 22, 2013

Object-Oriented Inheritance with JavaScript

JavaScript does not support an explicit inheritance operator the way Java or C++ do.
However, there are two ways to implement inheritance in JavaScript:

1. Using functions . This is the classical way.
2. Using Prototype. This is recommended and more powerful way of doing.  

Inheritance through Functions


1. Define super class.
2. Define sub class.
3. Assign the superclass object to one of the member method of the sub class.
4. Call the superclass constructor function inside the subclass.
/* Step 1 : define super class
*/
function superClass() {
this.sayHello = function(){alert('Hello SuperClass');}
this.sayMessage = function(){alert('Say Message SuperClass');}
this.name = 'superClass';
}

/*
Step 2: define sub class
a) assign the superclass object to one of the function object
b) call the superclass constructor inside the subclass
*/
function subClass()
{
//you can use any propertyname instead of parentClass eg superclass
this.parentClass = superClass;
this.parentClass(); // assigns the super class methods to subclass
this.sayHello = function(){alert('Hello SubClass');}
}

/* test */
function testSub() {
var sc = new subClass();
sc.sayHello();
sc.sayMessage();
}

Explanation


The explanation is pretty simple if you know the concept of “this” keyword in JS.
Remember that the ‘this’ keyword refers to the containing object.
So, when you call the following line, you have copied the entire superClass object to the subClass property
parentClass.
this.parentClass = superClass;
Then when you call the following line the constructor of the ‘superClass’ is fired.
this.parentClass();
Now, inside the superClass function you have the following line:
this.sayHello = function(){alert('Hello SuperClass');}
What does ‘this’ refer to?
Since the enclosing object of ‘superClass’ is ‘subClass’, the ‘this’ keyword refers to it’s enclosing object i.e.
“subClass” and not the ‘window’ object. Therefore all the properties of ‘superClass’ get copied to the ‘subClass’.

Inheritance through Prototype


This is the most suitable method of implementing inheritance in JavaScript.
1. The main advantage of this method is that the inheritance chain is dynamic i.e you can assign or remove   new methods and properties to the super class that becomes available to the child class automatically.
2. Also, JS natively supports prototypal inheritance and not class based inheritance.
3. We can only do method overriding and not method overloading.

Steps:

1. Create a super class.
2. Attach all the callable methods of super class to it’s prototype. Important step!
3. Create a sub class.
4. Assign the subclass prototype object to the super class instance. This creates inheritance.
5. Reset the constructor property for the sub class usingChildClassName.prototype.constructor=ChildClassName. This ensures that the objects created are
of the sub class and not the super class.
6. Call the super class methods using ClassName.prototype.methodName.call(this,parameters…). This will
work only for methods added via the prototype.

/* create a super class */
function Person()
{
this.sayName = function(){alert("Person::sayName()");}
this.name = "Person";
}
//create the callable methods in super using it's prototype
Person.prototype.sayHello = function(name){alert("Person::sayHello()");}

/* create sub class */
function Student()
{
this.name = "Student";
this.sayName = function(){alert("Student::sayName()");}
}

/* derive the sub class from super class by using it's prototype */
Student.prototype = new Person;

/*Reset the constructor property for the subclass using it's prototype.constructor property*/
Student.prototype.constructor = Student;
//add new methods to the super class which become available to all the sub classes automatically
Person.prototype.sayNew = function(){alert("Person::sayNew()");}
//call super class method
Student.prototype.callParentMethod = function()
{
//call parent methods this will work because sayHello is part of the object prototype
hierarchy
Person.prototype.sayHello.call(this);
//this NOT will work because sayName is NOT declared using the superclass prototype
Person.prototype.sayName.call(this); //error
}
function testProtoInherit()
{
var sc = new Student;
sc.sayHello();
sc.sayName();
sc.sayName('amit');
alert(sc.name);
sc.sayNew();
sc.callParentMethod();
}
testProtoInherit();
With Regards,
Animesh Nanda
Sr.Software Engineer | Photon Infotech
Bengaluru | Karnataka | INDIA.

Sunday, April 21, 2013

Javascript Prototype Object



Prototype is a builtin js property that is part of JS objects. It was introduced in JS version 1.1.
Prototype object can be added only to Function,String, Image, Number, Date and Array.
We can use prototype on the base class not on the objects derived from it.
The prototype object help you quickly add a custom method or member to an object that is
reflected on ALL instances of it.
Prototype object can only be used to add PUBLIC member and methods. It cannot add private
members or methods.
If the prototype object is used to override the the previously set property it will not override the
properties of already created objects. It will only affect the objects that have been created after
the prototype change.

Using prototype on custom objects:


var func = function(){};
func.prototype.foo = "bar"; //adds the property foo
alert(func.foo); //alerts undefined
func2 = new func();
alert(func2.foo); //alerts bar
func2.prototype.foo2 = 'ddd'; //Error : func2.prototype is undefined
Using prototype on builtin JS objects:

String.prototype.foo = "bar";
Image.prototype.foo = "bar";
Number.prototype.foo = "bar";
Array.prototype.foo = "bar";
You cannot use prototype on derived objects:
var str = new String();
str.prototype.foo = 'bar'; //Error : str.prototype is undefined




With Regards,
Animesh Nanda,
Sr. Software Engineer | Photon Infotech
Bengaluru | Karnataka | INDIA.