skip to Main Content

In the MDN documentation for "Statements and declarations" it is mentioned:

The terms "statement" and "declaration" have a precise meaning in the formal syntax of JavaScript that affects where they may be placed in code. For example, in most control-flow structures, the body only accepts statements — such as the two arms of an if…else. If you use a declaration instead of a statement, it would be a SyntaxError. For example, a let declaration is not a statement, so you can’t use it in its bare form as the body of an if statement.

The following code will give an error:

if(true) 
  let x = 0;

Now functions declarations are also just declarations right? Then why doesn’t the following code give the same error?

if(true)
function foo() {}

3

Answers


  1. if (true) {
      const foo = function() {};
    }
    

    In this case, the foo function will only be defined within the block of the if statement, adhering to block scope rules.

    Login or Signup to reply.
  2. Because declaring a function using the function keyword puts it in the global scope.

    Make a simple test:

    if (true) {
       function foo(x) { return x+2 }
    }
    console.log(foo(5))
    

    Will result in ‘7’ in the console, proving that the function was actually defined outside the if.

    On the opposite the variable explicitly defined inside the if will be scoped to the if.

    Note this code will raise an error because bar will not be defined outside the if.

    if (true) {
        const bar = function (x) { return x+2 }
    }
    console.log(bar(5))
    
    Login or Signup to reply.
  3. Edition 5.1 has a note specifically addressing this problem:

    Several widely used implementations of ECMAScript are known to support the use of FunctionDeclaration as a Statement. However there are significant and irreconcilable variations among the implementations in the semantics applied to such FunctionDeclarations. Because of these irreconcilable differences, the use of a FunctionDeclaration as a Statement results in code that is not reliably portable among implementations. It is recommended that ECMAScript implementations either disallow this usage of FunctionDeclaration or issue a warning when such a usage is encountered. Future editions of ECMAScript may define alternative portable means for declaring functions in a Statement context.

    From the next edition through the current one, the first construct is covered by an additional feature specified in Annex B, which is required when the host is a web browser:

    IfStatement[Yield, Await, Return]:

    if ( Expression[+In, ?Yield, ?Await] ) FunctionDeclaration[?Yield, ?Await, ~Default]

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search