Saturday, July 28, 2012

Inheritance in JavaScript

We all say we can have object oriented way of implementation in JavaScript. So lets see how can we inherit one class from another in JavaScript. In C# is very easy, writing a ":" will do it for you, but in JavaScript it is little tricky. We all know about prototype and constructor in java script(if you don't know please clear this concept from my previous post 'JavaScript tips and tricks -4'). In very simple words prototype gives you the instance of the base class and constructor gives you the instance of derived class.
Lets try to make inheritance between Pet and Dog class.
function Pet(name){
        this.getName = function(){return name;};
        this.setName = function(newName){name = newName;};
     }
function Dog(name, breed){
        this.getName = function(){return name;};
        this.getBreed = function() { return breed;};     
    }
Above code shows Dog constructor which takes name and breed as input and Pet constructor which takes name as input. Now we want to have toString method on Pet and Dog both. There are 2 ways to do it-
We can define it inside Class itself (perellel to this.getname method) or we can define it on prototype like this -
Pet.prototype.toString = function(){
        return "This pet Name is - " + this.getName();
    }
Dog.prototype.toString = function(){
        return "This is a Dog from prototype with NAme - " + this.getName() + " and Breed is - " + this.getBreed();
    }
If you remember from previous post how JavaScript execute any method on any object,you will understand the difference between 2 techniques.
Now lets put inheritance between these 2 classes -
    Dog.prototype = new Pet();
Now the prototype of Dog is a Pet, you can also call Dog as derived class of Pet.
Before we go into more detail of Dog and Pet, let me introduce one more property named as constructor.
consider another example -
function Person(){}
var p = new Person();
if(p.constructor === Person){
    alert('p.constructor === Person'); --> It will alert.
}
else{
    alert('p.constructor !== Person');
}
var p1 = new p.constructor();
if(p1 instanceof Person)
{
    alert('true'); --> TRUE
}
In the above example, if you see we created another object of Person using property constructor. Which means using constructor we can create object of same type, which can be proved once p1 instanceof Person alerts true. In order to achieve same objective we need to set the constructor property of Dog as well. But as we want this property to be there for all Dog objects, thus we will introduce it in the prototype function like this-
    Dog.prototype.constructor = Dog;
 If we dont set this property then we can't use this -
var dog1 = new dog.constructor();
It will not create another Dog object, instead it will create a Pet object, as constructor is available in Pet class.
If you remember inheritance in C#, whenever the object of derived class is initialized, its base class object need to initialized before that. The similar thing we will need to achieve in JavaScript as well to complete the inheritance. In order to do so, we can write call method of Pet in Dog constructor like this -
function Dog(name, breed){
        Pet.call(this, name);
        this.getBreed = function() { return breed;};      
    }
Now whenever a new Dog object is created it will automatically create Pet object as well. It completes our implementation of inheritance between Dog and Pet. Here is the full code -
    function Pet(name){
        this.getName = function(){return name;};
        this.setName = function(newName){name = newName;};
        //this.toString = function() {return "Pet with name " + this.getName();};
    }

    Pet.prototype.toString = function(){
        return "from prototype - This  pet Name is - " + this.getName();
    }

    var myPet = new Pet("pet1");
    alert(myPet);

    function Dog(name, breed){
        Pet.call(this, name);
        this.getBreed = function() { return breed;};
        //this.toString = function() {return "Dog with name " + this.getName();};
    }

    Dog.prototype = new Pet();
    Dog.prototype.constructor = Dog;

    Dog.prototype.toString = function(){
        return "This is a Dog from prototype with Name - " + this.getName() + " and Breed is - " + this.getBreed();
    }
    var dog = new Dog("Dog1", "Breed 1");
    alert(dog);

    alert(dog instanceof Dog);//true
    alert(dog instanceof Pet);//true
    alert(dog instanceof Object);//true
In order to check if inheritance was successful or not, you can always use "instanceof" method which gives true if the object is instance of given type.

Dog.prototype return object of Pet, which is base class for Dog.
constructor property returns you the constructor of that class. For example -
in above example dog.constructor does return constructor of Dog. It always possible to create another object (say dog1) of Dog using
var dog1 = new dog.constructor('dog2','breed2');

prototype can also used to modify existing object. For example we can add new method in inbuilt Array class -
if (!Array.prototype.forEach) {
  Array.prototype.forEach = function(fn){
    for ( var i = 0; i < this.length; i++ ) {
      fn( this[i], i, this );
    }
  };
}
var myArray = new Array('a', 'b', 'c');
myArray.forEach(function(value, index, array){
  alert(value + "-" + index + "-" + array)
});

Namespace in JavaScript-
JavaScript does support the namespaces. It helps us to avoid name collision. Here are some examples-
var namespace1 = {};
namespace1.var1 = function() {};
namespace1.var1.prototype.toString = function(){};

We can have multilevel namespaces also -
var namespace1 = {}
namespace1.namespace2 = {};
namespace1.namespace2.var1 = function(){};

Sunday, July 22, 2012

JavaScript Tips and Tricks -4

JavaScript Objects -
Javascript objects are dictionary. In C# you will find objects as an instance of class, but in Javascript every object is actually a dictionary.
var testObject = {};
 is equivalent to
var testObject = new Object();
We can set any property to JavaScript object using "." operator or "[]" operator. Here is the code snippet -

  var testObj = {};
  var testObj1 = new Object();
  testObj.myObj = '1';
  testObj1.myObj = '1';
  testObj["myObj1"] = '2';
  testObj1["myObj1"] = '2';

alert("testObj.myObj--" + testObj.myObj); // alert -1
alert("testObj1.myObj--" + testObj1.myObj); // alert - 1
alert("testObj[myObj1]--" + testObj.myObj1); // alert -2
alert("testObj1[myObj1]--" + testObj1.myObj1); // alert -2


In the above code testObj.myObj and testObj1.myObj are same and can be accessed by "." operator or "[]" operator.

JavaScript Functions-
JavaScript functions are objects with executable code associated with it. Here are 3 different ways of defining same function -
1)
    function test1(x){
    alert(x);}
    test1('myName');
2)
    var func = function(x){
    alert(x);}
    func('myName');
3)
    var func = new Function("x" ,"alert(x);");
    func('myName');
This shows functions are actually objects which supports a function call operation. The following examples shows we can add properties also to the function -
function test1(x){
    alert(x);
    }
    test1('myName');

    test1.text = "myText";
    test1['text1'] = "Another Text";

    alert(test1["text"]);
    alert(test1["text1"]);
    alert(test1.text);
    alert(test1.text1);
It will alert "myText" "Another Text" "myText" "Another Text".

Its possible to pass a function as an argument to another function -
     function square(x){
    return x*x;
    }   
    function operateOnFunc(x, func){
        return func(x);
    }   
    alert(operateOnFunc(4,square)); // alerts 16

Function can be returned as a value from another function -
 function makeSquare(){
    return function (x){ return x * x ;};
 }
 var ans = makeSquare();
 alert(ans(7)); // alerts 49

Constructor function -
In Javascript there is no class/structs. If we want to define any object of our custom type, we use functions. Consider following example -
function MyClass(name){
this.name = name;
    this.respondTo = function (name){
    alert("Hi " + this.name );
    }
}var myObj = new MyClass('class1');

what "new" operator does is, it creates new empty object and execute the function on that empty object. In other word new operator is equivalent to -
var myObj = {};
MyClass.call(myObj, 'class1');

Prototype -
The prototype object is a central concept in object oriented programming with JavaScript. Every properties and methods of prototype object will appear as properties and methods of the object created from prototype constructor. In JavaScript every function has property named as "prototype" that refers to prototype object and this prototype object has property named as "constructor" which refers to this object back.
Lets consider a Dog class to understand different scenario of prototype-
function Dog(name){
this.name = name;
    this.respondTo = function (name){
    alert("Hi " + this.name );
    }
}
 var spot = new Dog("Spot");
 alert(Dog.prototype.isPrototypeOf(spot)); // true
 alert( spot.constructor == Dog.prototype.constructor); // true
 alert( spot.constructor == Dog); // true

The constructor property belong to prototype not to original object.
alert(spot.hasOwnProperty("constructor")); // false
alert(Dog.prototype.hasOwnProperty("constructor"));//true
Note - you wont find prototype method on spot, you will find it on Dog.
Every new instance of Dog will share the same prototype object.

Even if objects share the same prototype object then also making change in prototype by one object wont reflect on other. Here is the example -
 function GreatDane(){};
var rover  = new GreatDane();
var spot = new GreatDane();

GreatDane.prototype.getBread = function (){
     alert( "Dane");
}
spot.getBread(); //Dane
rover.getBread(); //Dane

//hides getbread in greatDane.prototype
spot.getBread = function (){
alert( "spot");
}
spot.getBread(); //spot
rover.getBread(); //Dane
Changes to getBread never propagate to prototype.

Every JavaScript object inherits chain of prototypes, all of which ends with Object.prototype. Object.prototype is ultimate prototype for all prototypes in JavaScript. The prototype of Object.prototype is null.
Here is the flow which gives insight of how toString() method get resolved in JavaScript -

Static Properties-
Static fields are bound to class not to instance of the class. Creating static properties in JavaScript is easy as functions are objects whose properties can be set on desire. Since constructor function represent a class in JavaScript you can add static properties of that class simply by setting to constructor of that class. Here is the example -
function myFunc(){}
    myFunc.myStatic = function() {
        return "Hi";
    }
alert(myFunc.myStatic());

Reference - http://msdn.microsoft.com/en-us/magazine/cc163419.aspx

Saturday, July 21, 2012

LINQ


1) Which of the following will facilitate you where method in object of MyCollection
a) MyCollection<int> : IEnumerable<int>
b) MyCollection : IEnumerable<int>
c) MyCollection : IEnumerable
d) MyCollection<int> : IEnumerable

Ans - a and b.
NOTE- "Where" method is available in generic IEnumerable.

2) What will be the output of following program?
var primes = new List<int>() { 1,2,3,8,5,12,78,09,23};
var query = from num in primes
where num < 5
select num;
foreach (var i in query)
{
Console.WriteLine(i);
}
Ans -
1
2
3

3) Write Above example in form of filter(where) and projection(select) format.
Ans -
var primes = new List<int>() { 1,2,3,8,5,12,78,09,23};          
var query = primes.Where(num => num < 5).Select(num1 => num1);
foreach (var i in query)
{
Console.WriteLine(i);
}
NOTE - "where" statement is considered as filter and "select" statement is considered as projection in LINQ.

4) A same query can be written is following 2 formats-
var query = primes.Where(num => num < 5).Select(num1 => num1);
var q = from p in primes where p < 5 select p;


5) What is the output of following-
var primes = new List<int>() { 1,2,3,8,5,12,78,09,23};
Console.WriteLine(primes.GetType());
Ans - System.Collections.Generic.List`1[System.Int32]
NOTE- variables and objects declared with var are type safe. If we hover hover cursor over variable name , then it will show original type of that variable.


7) What do you mean by Deferred execution in LINQ?
Deferred execution means that the evaluation of an expression is delayed until its realized value is actually required(Source MSDN).In other words it is lazy evaluation of query(LINQ statement). For example -
var primes = new List<int>() { 1, 2, 3, 8, 5, 12, 78, 09, 23 };
var query = primes.Where(num => num < 5).Select(num1 => num1);
foreach (var i in query)
{
Console.WriteLine(i);
}
In the above code query(LINQ statement) wont be evaluated until foreach is run.

8) What will be the output of following program-
  static void Main(string[] args)
        {
            var books = GetBooks();
            var query = from b in books select b.Authors;
            foreach (var qr in query)
            {
                Console.WriteLine(qr);
            }
        }
        private static List<Book> GetBooks()
        {
            var books = new List<Book>()
            {
                new Book{Title = "Title1",Authors = new List<Author>(){new Author{FullName = "Author1"}}},
                new Book{Title = "Title2",Authors = new List<Author>(){new Author{FullName = "Author3"}}}
            };
            return books;
        }
    }
    class Author
    {
        public string FullName { get; set; }
    }
    class Book
    {
        public string Title { get; set; }
        public List<Author> Authors { get; set; }
    }
Ans -
System.Collections.Generic.List`1[LinqTest.Author]
System.Collections.Generic.List`1[LinqTest.Author]
NOTE- People might think it will print Author1 and Author3. But actually the query return the Author object of Book class, which is a string. If you want to print the author name then we will need another foreach loop in the Authors list and print the fullname as well.

9) In the above example how can we print Author full name?
Ans -
var books = GetBooks();
var query = books.SelectMany(book => book.Authors);
//var query = from b in books select b.Authors;
foreach (var qr in query)
{
Console.WriteLine(qr.FullName);
}
SelectMany projects each element of as sequence to an IEnumerable and flattens the resulting sequence into one sequence.

10) What will be output of this code(focus on selectMany) -
static void Main(string[] args)
        {
            var books = GetBooks();
            var query = books.SelectMany(book => book.Authors);
            foreach (var qr in query)
            {
                Console.WriteLine(qr.Address);
            }
        }
        private static List<Book> GetBooks()
        {
            var books = new List<Book>()
            {
                new Book{Title = "Title1",Authors = new List<Author>(){new Author{FullName = "Author1",Address= new List<string>{"Bldg1","Street1"}},new Author{FullName = "Author2",Address= new List<string>{"Bldg2","Street2"}}}},
                new Book{Title = "Title2",Authors = new List<Author>(){new Author{FullName = "Author3",Address= new List<string>{"Bldg3","Street3"}},new Author{FullName = "Author4",Address= new List<string>{"Bldg4","Street4"}}}}
            };
            return books;
        }
    }
    class Author
    {
        public string FullName { get; set; }
        public List<string> Address { get; set; }
    }
    class Book
    {
        public string Title { get; set; }
        public List<Author> Authors { get; set; }
    }
Ans -
System.Collections.Generic.List`1[System.String]
System.Collections.Generic.List`1[System.String]
System.Collections.Generic.List`1[System.String]
System.Collections.Generic.List`1[System.String]

11) How will you print the address of every author in above code?
Ans - Use var query = books.SelectMany(book => book.Authors).SelectMany(author => author.Address);
instead of var query = books.SelectMany(book => book.Authors);

12) If I use following query(replace selectall with select) then what will be the output ?-
var query = books.SelectMany(book => book.Authors).Select(author => author.Address);
Ans -
System.Collections.Generic.List`1[System.String]
System.Collections.Generic.List`1[System.String]
System.Collections.Generic.List`1[System.String]
System.Collections.Generic.List`1[System.String]