2

Consider the following code (http://jsbin.com/vewot):

var shouldDefine = false;

if(shouldDefine) {
    function something() {
        var a = 1;   
    }
} 

alert(typeof something);

What would you expect the alert to show? For me, I would expect it to say "undefined", because the if block should not be run, since shouldDefine = false. And in Firefox, that is what happens.

But in Chrome and IE9, it says 'function'! Is this a browser bug or is this legitimate JavaScript behavior?

Denys Séguret
  • 372,613
  • 87
  • 782
  • 758
jwl
  • 10,268
  • 14
  • 53
  • 91
  • 2
    There's no such thing as a function declaration inside a block according to the ECMAScript specification; any attempt to support one is a implementation-defined behavior. (cf. [Function Declarations Within Blocks according to the Google JavaScript style guide](http://stackoverflow.com/questions/17409945/function-declarations-within-blocks-according-to-the-google-javascript-style-gui/17410055#17410055)) – apsillers Sep 08 '14 at 18:44
  • @apsillers It's not clear to me if we should close as duplicate or not. – Denys Séguret Sep 08 '14 at 18:46
  • 1
    That code is erroneous in "strict" mode. – Pointy Sep 08 '14 at 18:48
  • @dystroy Though the underlying JavaScript mechanisms involved are the same, I think the concerns of the questions are sufficiently different. (That other question asks about a style guide and doesn't understand what a block is, this question asks about observed behavior.) I agree it's a bit gray, but I'll reserve my close vote -- I think a non-duplicate link to the other question is probably enough. – apsillers Sep 08 '14 at 18:53

2 Answers2

3

Normally, the behavior of such a declaration is to have that function, as for any variable, declared for the current scope, which is either the global scope or the function call (in ES5).

That is : normally, this function is defined independently of the value of the test : the test is useless, the function declaration is "hoisted" to the beginning of the enclosing function, as if that test weren't present, whatever its result.

But there was a bug in some versions of IE where the test was used to define the function, which makes this code, from that time, considered as undefined behavior (the specification of that case wasn't very clear to start with). And a function declaration in an internal block isn't even valid in strict mode.

Denys Séguret
  • 372,613
  • 87
  • 782
  • 758
0

You cannot define a function in an if block. As people have already said, that is implementation-defined behaviour. However, Functions are also objects, so you can assign them to a variable like this:

var shouldDefine = false;
var something;

if(shouldDefine) {
    something = function () {
        var a = 1;   
    };
} 

alert(typeof something);

this will alert 'undefined' if shouldDefine is false and 'function' if it is true.

Ferdi265
  • 2,879
  • 1
  • 17
  • 15