Saturday, October 30, 2010

Javascript prototype property

Today, in this post, I am going to discuss about the prototype property of classes in javascript. I came across this property when i was trying to learn about classes in javascript. Javascript, being a dynamic language, allows you to have a number of bizarre yet interesting features that you don't find in mainstream languages. the prototype property is one such feature. Due to its idiosyncrasy, it is usually a source of confusion. I am just going to brush on the basics here so that it becomes easy for us to spot loopholes in the more complex code that we usually write.

Here are our objectives.

  1. Learn where and why the prototype property is usually declared in javascript.
  2. Learn how to use the prototype property in javascrpt.


First, lets try to explain why the prototype property is used in javascript.
The prototype property comes in handy when you have a class and you have already created a set of objects and at a certain point of time, you want to introduce a new property in each of your objects.

Lets see with an example. First we create a class called Person with a property called name

function Person(name){
      this.name = name;
      this.getName=function(){return this.name;};
      
      this.setName=function(nameArg){
       this.name=nameArg;
      };
     }

Then we create a few objects of this class as follows.


var p1= new Person("person1");
var p2= new Person("person2");


Now suppose that need to add a property called 'age' for all the person objects that are currently created. The first way that might come to our mind is to modify the class declaration and add a new property called age to it in the same way that we added name property. But what if the class Person is declared in some common file and is referenced by different scripts, and my requirement necessitates that the new property should be available only for the currently executing script. This is where the prototype property comes to the rescue.

We can add a property to all the instances of the class by writing the following lines of code.

var p1= new Person("person1");
     var p2= new Person("person2");
     
     Person.prototype.age=30;
     
     console.log(p1.age);
     console.log(p2.age);


As seen in the above code, when i print the value of the variable age, both the objects are able to print the new property.

An interesting thing to not here is that the property called age that has been newly created here is actually a class variable. i.e. all the objects created are able to see the same value of the newly added property. What this means is that if we try to modify the property via one variable, all the objects will see the new value of the property. Since objects are equivalent to functions in javascript, the prototype property can be used to create new functions on the class as well.

Lets modify the code for the Person class by adding a function to set the age.

this.setAge=function(argAge){
       Person.prototype.age=argAge;
      }

So far so good.

Now, lets see what happends when we print the age of the objects after modifying the age for one of the objects.

Person.prototype.age=30;
     Person.prototype.setAge=function(argAge){
       Person.prototype.age=argAge;
     }
     
     
     console.log(p1.age);
     console.log(p2.age);
     
     p1.setAge(40);
     
     console.log(p1.age);
     console.log(p2.age);


If you run this, you would see that both the objects p1 and p2 have the same value of age after being modified. So, after all, what was the use of creating a new property if it is being shared across all the objects. Also, we saw that in the setAge function that we are using the fully qualified syntax to access the age property. Lets see what happens if we use the shorthand notation in the setAge method.

Person.prototype.setAge=function(argAge){
       this.age=argAge;
     }

     console.log(p1.age);
     console.log(p2.age);
     
     p1.setAge(40);
     
     console.log(p1.age);
     console.log(p2.age);

Now, if you were to print the age of the two objects, they would differ. Seems like our problem is solved. But what actually was the cause of the problem in the first place? The problem arises due to the way in which the javascript engine searches for the age property on the object.

When trying to access the age property, the engine will first search the property on the instance of object. i.e. this.age. If this property is not available on the object then the engine will search for the property in the prototype property. Since the variable 'age' is declared on the prototype, it is found and printed on the console when we try to print it for the first time.

But when we set the property using the setter method using the "this.age=argAge", a new property is created on the current instance and its value will be set to the value passed as the argument.

You might be wondering, what is the use of creating a property using the prototype method. The main advantage that you get by using the prototype property is that you can create new class level properties or functions at runtime without modifying the class. And from then on you can read the value of this property from all the instantiated objects. You can then also create a property of the same name on the objects using the value of the prototype property.

For example

Person.prototype.addAge=function(){
      this.age=this.age+1;
     }

p2.addAge();
     
     console.log(p2.age);


In the function addAge, the "this.age" on the RHS will refer to the Person.prototype.age the first time it is called and the "this.age" on the LHS will create a new public property called "age" on the current instance. Further invocation on the method will cause the newly created publicly created property.

Thats all for now folks!

Happy Programming :)
Signing Off
Ryan

Javascript classes

In this post, i am going to discuss how to create classes in javascript and how classes in javascript behave differently as compared to classes in other languages like Java.

Here are our objectives.

  1. Learn how to create javascript classes.
  2. Learn how to create properties in javascript classes.
  3. Accessing the properties of javascript classes.


Lets walk through them one by one.

In javascript, classes are created by merely creating a constructor function of the class. The functions declared within the constructor on the 'this' object become the "public" functions of the class. The variables declared within the function on the "this" object become the "public" variables of the class.

Lets see with an example of a class called person.

function Person(name){
      this.name = name;
      this.getName=function(){return this.name;};
      
      this.setName=function(nameArg){
       console.log(nameArg);
       this.name=nameArg;
      };
     }

As seen above, i created a function named Person. Then i created a property called name on the "this" object. And i also created a bean style getter and setter for this property on the "this" object. Here is how we instantiate the class.

var p1= new Person("ryan");

As you see, instantiation is pretty simple and quite similar to your conventional languages like Java.

Now lets see how to invoke the methods and access the properties.

console.log(p1.name);
     
console.log(p1.getName());
     
p1.setName("public name");
     
console.log(p1.getName());


Note that the property "name" is a public property, because it is declared on the this variable. So, it can be accessed without any getters and setters. I have simply introduced getters and setters for the "name" property to demonstrate how private properties differ from public properties, which i will be covering in the next example.

So far, so good.

Now lets see how the code for the person class would change if i were to make the "name" property private.

function Person(){
      var name;
      this.getName=function(){return name;};
      this.setName=function(nameArg){       
       name=nameArg;
      };
     }


Okey, lets make a note of the differences. First thing you see is that i created a property called "name" using the var keyword. Now it is a private variable. The point here is that all the variables declared in side a class, that are not declared on the this variable are private variables. And the public getter/setter functions, are allowed to set and get the private variable directly without any using the "this" keyword. This is possible due to javascript closures. Closures allow you to access locally declared variables from with locally declared methods. And the scope of the local variable lasts as long as the scope of functions where it is being used.

As i said before, if all local variables are private variables, then the following class declaration should be equivalent to the previous one for declaring private properties.

function Person(name){
      this.getName=function(){return name;};
      this.setName=function(nameArg){
       console.log(nameArg);
       name=nameArg;
      };
     }

And guess what, they are equivalent. Thats because, the variable passed as an argument in a constructor is a local variable in the function, just as in Java. Hence, it automatically becomes a private variable.

Here's how it can be accessed

console.log(p1.getName());
     
     p1.setName("surprise");
     
     console.log(p1.getName());

Pretty simple.

However, it is better not to have private variables and corresponding getter and setter methods for them because for each object that you create, a new copy of the methods would be created for each object, and hence it would have significant memory overload if you intend to create several objects. Its always better to create public properties and mainly use function pointers instead of functions in your classes. Ill be discussing about these topics in my upcoming posts.

Till then.
Hasta La Vista!

Happy Programming :)
Signing Off
Ryan

Monday, October 18, 2010

Struts 2 - Creating Dynamic results

Hi everyone,

Today, in this blog post, I am going to jot down a way to create dynamic results in struts 2.

Lets first begin with a few questions.

What do i mean by dynamic results?


We all know that struts allows us to configure the pages to which request must be dispatched to redirected to, via the "result" tag. However, at times, it may be hard to determine at configuration time itself, which pages need to be set as the result. For example, your business logic may determine the action or the jsp that you need to forward to. In the following example, I am going to try and allow the dynamic results in Struts 2.


Whats my objective?


To create an action class that determines the jsp page name that we need to forward to based upon some business logic.
Configure the action in my struts configuration file(struts.xml) for dynamic results
Invoke the action.


Now, lets begin.

Firstly, we create an action class called DummyAction2. (STATUTORY WARNING : The naming conventions in this post, and for the record, many others, might sound bit weird, but i have a tonne of experiments, and its really hard to settle on a proper name for every whim that comes to my mind. So, please bear with me on that note. :> )

My action class is like any other action class. It contains an execute method. But in my case, the execute method does not do anything, except return a "success" string. Thats because i have another business method, which i am going to name as(surprise! surprise!) anotherMethod. This is the method that i am going to invoke using my action mapping.

In order to be able to identify the page that we need to display, we need to create an instance variable that holds the name of the page that we need to forward to. And we create getter/setter methods for this instance variable.
Ill just keep the business logic simple, and store the name of the next page to be displayed, in this instance variable when the action is invoked.

Lets take a sneak peek at the code in the action class.


public class DummyAction2 extends ActionSupport{

    private String nextPage;

    public String execute()
    {
        return ActionSupport.SUCCESS;
    }

    public String anotherMethod(){
        String actionStatus=ActionSupport.INPUT;
        System.out.println("Another Method in Dummy Action");
        
        nextPage = "myPage.jsp";

        actionStatus=ActionSupport.SUCCESS;
        return actionStatus;

    }
    /**
     * @return the nextPage
     */
    public String getNextPage() {
        return nextPage;
    }

    /**
     * @param nextPage the nextPage to set
     */
    public void setNextPage(String nextPage) {
        this.nextPage = nextPage;
    }
}

As you see, there's nothing much going on in my anotherMethod. All i do is to set the value of the next page in the instance variable. And then i simply return a success response from the action class.

The mapping is where the real magic takes place. In your mappings, you can dynamically determine the value of a variable in an action using ordinary EL. Lets see the code first.


                ${nextPage}
            

Okey, i was lying. Its no magic. Its just that, in your struts configuration file, you can access the properties in your current action class using ordinary EL. Thats exactly what we have done here. The string ${nextPage} is used to extract the value of the property named "nextPage" from the current action. And since that action is a jsp page in our case, that's the page that will be rendered to the user.

Invoking the action is done in the same old fashioned way.

Invoke Dynamic Result

I guess, the idea is pretty clear.

Thats all for now. See you folks next time!

Happy Programming :)
Signing Off
Ryan