Saturday, December 28, 2013

javascript internals: scopes

Now here is something that can definitely tease the programmer in you.

Someone in stackoverflow asked a question related to javascript. It goes something like this:

Snippet 1:

<script type="text/javascript">
	function MyFunc() {
		alert(1);
	}
	var f1 = MyFunc;	
	function MyFunc() {
		alert(2)
	}
</script>
<script type="text/javascript">

</script>
<script type="text/javascript">
	f1();	
</script>

f1() outputs 2 in a message box. This is acceptable and expected.

Snippet 2: 

<script type="text/javascript">
    function MyFunc() {
        alert(1);
    }
    var f1 = MyFunc;
</script>
<script type="text/javascript">
    function MyFunc() {
        alert(2)
    }
</script>
<script type="text/javascript">
    f1();
</script>
 f1() outputs 1.

Wait...what the hell just happened? Isn't the above two snippets equivalent?

You can try it out at jsbin, or jsfiddle, or whatever place, but you'd still end up with the same observation.

My answer relates the idea of scoping that takes place in a script block. A whole new scope is created for the entire code inside a script block to run in. Hence for our 2nd case, we have MyFunc defined in scope 1 - i.e. the scope of the first script block. So MyFunc is now an object which is created with scope 1. f1 now points to this object.

When the second script block is executed, we have MyFunc created in a new scope. Hence a new object is created in that scope. So the MyFunc created in the first scope is not the same MyFunc created in the second scope. They are essentially two separate objects. And now since f1 points of the first object created; calling the method pointed by it will output a message box saying 1.

In the first snippet. The object is created only once. However, MyFunc is defined twice in the same scope. Hoisted I believe is the correct term to use here. So, one object is created, and, that object, is associated with the most recent definition. Hence the call to f1 will output a message box saying 2.

Upvote my answer if you agree with the explanation, else you can provide your own comments there.

Happy programming...