Did you know that JS can be weird sometimes?

Of course you did, otherwise you wouldn’t read this! Anyway, I found this little easter egg in Javascript land:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
function test(){
    var privateVar = 10;
    function tryXs(){
        if (false) {
            var privateVar = 5;
        }
        alert(privateVar);
    }
    this.callme = function(){
        tryXs.call(this);
    }
}
 
var oTest = new test();
oTest.callme();

Now what do you think what will the alert() show us? UNDEFINED! Now why would that be???
Well, apparently the ‘var’ in

1
2
3
if (false) {
    var privateVar = 5;
}

screws things up for us; even though the if-statement is evaluated to FALSE at all times, thus never executing the statement body (’var privateVar = 5′). Reasonably, you’d expect the alert dialog to display the value ‘10′, but apparently it still parses the body of the if-statement and pulls a string of the variable scoping rules.
Want to hear something even more weird? It’s consistent behavior! This occurs in all major browsers (I tested IE 6, FF 3.0.1, Opera 9.51 and Safari 3.1.2) and the alert shows ‘10′ when you remove the ‘var’ from ‘var privateVar = 5′. That actually makes sense again!

I’m quite interested to see and hear if anyone can give me an explanation for this behavior, because I probably lack the skill(s) to see any practical use in this ‘feature’ ;).
Does anyone else know a weird Javascript nugget like this?

Share and Enjoy:
  • Print
  • Digg
  • del.icio.us
  • Facebook
  • Google Bookmarks
  • Fleck
  • Reddit
  • Technorati

6 Responses to “Did you know that JS can be weird sometimes?”


  • Actually, its because you’re never parsing test(). You create an instance of it, and then only call callme, which only calls tryXs, so privateVar is never ever defined since thats in the test.call itself. You need to define privateVar in tryXs or call test first, probs best to set it static if thats the case.

  • hmm actually no, you’re right - i didn’t read the part about the var in the if (false) :| so it is trying to define an already defined variable (although isn’t because the statement is false) but because it has already parsed the line, somewhere in the full parsing by the interpreter the interpreter has assumed something and screwed up. Lemme test in chrome, one sec.. yep chrome screws up too. I’d hazard a guess to say its a parsing error, the script gets parsed and the part which sets the variables (in the parser) is seeing the same declaration twice, but is then being superseded by the if (false) logic, so it reverses the variable definition, which in turn fucks up the original definition because it was superseded by the second. At least thats my theory =P

  • Azrul Syahriman Bin Salleh

    This is something.

  • functions are designed to be nested within other functions to create a closure — or a transparent link to it’s parent functions context. If you use the ‘var’ keyword, the intrepreter thinks you will be redefining that var, so it does it for you just prior to the function actually begins to run, hence breaking the closure to the var defined in it’s parent.

  • You should never declare a variable into a conditional (if, while, etc.).

    You should declare your variable before with a default value, and then use it in a “if”. Its a common rule in all languages, or?

  • it’s not weird. it is natual.

Leave a Reply