Saturday, June 26, 2010

Javascript functions - Part 2

This is the continuation of my previous blog post here wherein I discussed the very basics of functions in javascript. This, and a few more posts will build upon it by exploiting the nature and relationship between objects and functions in javascript.

Today, here, I am going to explore the ways in which javascript functions can be invoked. Although i won't be discussing all the possible ways as i am yet to experiment with each one of them, however, the below examples would act as a good starter.

Ok, lets get down to the nitty-gritty.

Function calling. Pretty simple eh? Whats the big deal about them that made me want to write a post about them? Well, although its not a big deal, it can get a bit confusing at times for an OOPS programmer like me when i see code given in the below examples for the first time.

Lets start with the standard way.

As in all programming languages, invoking a function in javascript is achieved by using the function name, the parenthesis and specifying its arguments.


Here is an example;

function fun1(){
   console.log("hi. fun1 here.");
  }
  
  fun1();

Nice and simple. I just called a function having no arguments, that prints a message on your browser console(Firefox. You need to have the Firebug plugin for console.log to work. Its a pretty good tool. If you haven't been using it already, now would be the right time to start.)

Lets see another example

function fun2(arg){
   console.log("hi. fun2 here. Argument : " + arg);
  }
  
  fun2('ryan');

This is pretty simple as well. I am just calling a function fun2 having a single argument. But you already know that, dont you?

Now lets see a 'Second way' way to call a function.


(function fun3(){
   console.log("hi. fun3 here.");
  })();

Whoops! Did you get it at the first glance? If you are astute observer, then you might have noticed, but if you are like me, then you would still be pondering for a while before completely absorbing what the new syntax actually does.

Read the code once more, and I think you will figure it out. The funny thing about this snippet is that not only is it a function declaration, but it is a function invocation as well. Let's see how.

First, you need to note that you have created a function inside a parenthesis. This parenthesis is followed by another pair of parenthesis. Inside your first parenthesis, you create a function definition and print a message to the console. The function is named fun3.

Once you are out of the first parenthesis, the function definition and declaration are complete. Now all that you need to do is to invoke your function. That task is performed by your second pair of parenthesis.

Okey, thats simple. But how do you call a function with arguments?
That's pretty simple as well.

(function fun3(arg){
   console.log("hi. fun3 here. : " + arg);
  })('ryan');

As you see, we simply passed in the argument in the parenthesis that are used to invoke the function.

But there is something that makes this 'Second way' of invoking your function, a bit different from the first way of calling.

As you have seen, my function fun3 was declared and defined inside a parenthesis. And was invoked by another set of parenthesis. But if you try to invoke this function again, using a call like fun3(), it wont work. Why wont it work? Because the scope of your declared function - fun3, is only up to the the first pair of enclosing parenthesis. The moment you invoke the function, the function is no more.

That explains why the following piece of code won't work

(function fun3(){
   console.log("hi. fun3 here." );
  })();
  
  fun3();

This is because, by the time the javascript engine comes to the line where you are invoking fun3 using the syntax fun3(), the function is no longer in scope.

The implication of this is that such functions can be used to easily perform one time tasks, and the names of such functions will never clash with any other global function and object names. For example the following code will print both, the first message and the second message, in spite of the names being the same.

(function fun3(){
console.log("scoped : hi. fun3 here."); })(); function fun3(){ console.log("global : hi. fun3 here."); } fun3();

This will work even if you reverse the order in which you declare and invoke the function. For example, the following will work as well.

function fun3(){
   console.log("global : hi. fun3 here.");
  }

(function fun3(){
   console.log("scoped : hi. fun3 here.");
  })();
  
  fun3();


There is an interesting inference that can be made from this observation. If the name of the function declared within the first parenthesis have no impact whatsoever, then why do we have to declare a name in the first place? Well, do we?
Fortunately, javascript allows us to have anonymous functions. In fact, all javascript functions are anonymous functions when they are declared, and they are simply assigned to variables so that they can be invoked.

Well, that means that the following piece of code should work just fine. And guess what, it simply does work!

(function (){
   console.log("anonymous : Hi. Mr anonymous here.");
  })();

Now, is'int that beautiful? It sure is.

Although there are a few more ways of invoking functions, we will delve into it in another post as that requires a bit more knowledge of some other javascript features as well. For now, this should suffice as introduction.In The next part of this series we will check out some more implications of the Second way of invoking functions that has been discussed here.


Happy Programming :)
Signing Off

Ryan

No comments: