Feed Sign in with OpenID OpenID

Simon Willison’s Weblog

Internet explorer mystery #1376. IE executes function definitions inside an “if (0)” block. That frightens me.

Tagged , ,

5 comments

  1. This actually isn't too crazy. I posted a comment on the actual post, but I wanted to post here also for people who only see this page.

    There are function statements and function expressions in Javascript. Function statements define a function in the enclosing scope whereas function expressions can be assigned at the time you need them to be available.

    Hsiu-Fan Wang - 3rd December 2008 09:53 - #

  2. This isn't as weird as it sounds.

    What do you think this will alert...

    var hello = "hello";
    (function() {
      if (0) {
        var hello = "HELLO";
      }
      alert(hello);
    })();

    It alerts 'undefined'. The 'hello' var is created inside closure, although it isn't assigned a value. This is correct according to the ECMA spec.

    Considering the following works...

    shout();
    function shout() {
      alert("Oi!");
    }

    ...I can kinda understand why IE would pick it up in an if(0)

    Jake Archibald - 3rd December 2008 10:41 - #

  3. I'd agree with Hsiu-Fan - given JavaScript's known scoping issues, I actually expect this to happen in all browsers (it does happy in Safari too). However, particularly after reading Crockford's Good Parts, that particular coding pattern should be avoided - rather than relied on, in favour for something like var fn = function () {}; within the if block.

    Remy Sharp - 3rd December 2008 10:42 - #

  4. In a similar note:

    world(); // Most browsers get an undefined error here
    hello(); // IE gets an undefined error here
    
    var hello = function world() {
      alert("Hello world");
    }

    IE's behaviour makes more sense to me, considering the last example in my previous post. Although I'm sure it's incorrect according to the spec.

    Jake Archibald - 3rd December 2008 11:11 - #

  5. Just to muddy the waters further, what should we expect the following to do? It needs to be inside a script block, not executed in FireBug:

    if (typeof really == "function") {
      function really() {
        alert("Yes, really");
      }
    }
    
    really();
    
    function really() {
      alert("Original");
    }
    

    In this case, IE, Chrome and Opera say "Original", but Firefox says "Yes, really". I think Firefox gets this right, but it's all a bit dubious. There's definitely some ambiguity about what should happen when the top-level functions are initially parsed out, and what should happen at runtime.

    This one is even weirder:

    
    if (typeof really == "function") {
      function really() {
        alert("Yes, really");
      }
    } else {
      function really() {
        alert("No way!");
      }
    }
    
    really();
    
    {
      function really() {
        alert("Original");
      }
    }
    

    Firefox says "No way!"--seems that it defers evaluation of functions declared within any scope block. The others all say "Original". Pretty dodgy. Fortunately, I doubt anyone would code against this behaviour in the first place.

    phl - 3rd December 2008 14:52 - #

Comments are closed.
A django site