JavaScript: Broken as intended

This is in no way me bashing JavaScript; I love JavaScript. This is me, finding something that, despite being seemingly wrong, is there by design. Take this example:

var a = 100;
(function (){
alert(a); // alerts undefined
var a = 20;
alert(a); // alerts 20
}());

If you had experience in other languages, but little with JavaScript, you may think it would alert 100, then 20, but it does not. Because a variable “a” exists in the scope of the closure (inside the anonymous function) it won’t use the “a” further up the scope chain, it will instead use the a inside the closure, even if it’s not yet defined. I could see this getting very confusing for someone who doesn’t have experience in JavaScript, and even then, it will be confusing the first time you see it. To help understand this point, try removing the “var” from the “a” in the closure; it will now alert 100 and 20, respectively, using the first “a” it can see.It seems, the local scope is first checked (all of it, even what has not yet been defined) and if it’s not found, it looks to the next scope up. I am sure there is a more technical explanation, about closures and scope chains, but I wanted to keep this simple. I may elaborate more later when I understand more

Advertisements

One Response to “JavaScript: Broken as intended”

  1. Also interesting to point out is that this goes beyond scope: scope is indicated with {}, whereas this is an anonymous function definition that lives completely separated from whatever function you’re defining it in. Whether you define it as:

    function a()
    {
    var a = 20;
    var b = (function() { return a + 20; })();
    }

    or as:

    function a()
    {
    var a = 20;
    var b = added();
    }

    function added()
    {
    return a + 20;
    }

    these are the same thing. So the only way to get values into a function is by passing them explicitly:

    function a()
    {
    var a = 20;
    var b = (function(input) { return input + 20; })(a);
    }

    which is of course functionally equivalent to:

    function a()
    {
    var a = 20;
    var b = added(a);
    }

    function added(input)
    {
    return input + 20;
    }

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: