Lint Rules

noInnerDeclarations (since vnext)

Disallow function and var declarations in nested blocks.

A function and a var are accessible in the whole body of the nearest root (function, module, script, static block). To avoid confusion, they should be declared to the nearest root. Note that const and let declarations are block-scoped, and therefore they are not affected by this rule.

Moreover, prior to ES2015 a function declaration is only allowed in the nearest root, though parsers sometimes erroneously accept them elsewhere. This only applies to function declarations; named or anonymous function expressions can occur anywhere an expression is permitted.

Source: https://eslint.org/docs/rules/no-inner-declarations

Examples

Invalid

if (test) {
    function f() {}
}
nursery/noInnerDeclarations.js:2:5 lint/nursery/noInnerDeclarations ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

   This function should be declared at the root of the module.
  
    1 │ if (test) {
  > 2 │     function f() {}
       ^^^^^^^^^^^^^^^
    3 │ }
    4 │ 
  
   The function is accessible in the whole body of the module.
    To avoid confusion, it should be declared at the root of the module.
  
if (test) {
    var x = 1;
}
nursery/noInnerDeclarations.js:2:5 lint/nursery/noInnerDeclarations ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

   This var should be declared at the root of the module.
  
    1 │ if (test) {
  > 2 │     var x = 1;
       ^^^^^^^^^
    3 │ }
    4 │ 
  
   The var is accessible in the whole body of the module.
    To avoid confusion, it should be declared at the root of the module.
  
function f() {
    if (test) {
        function g() {}
    }
}
nursery/noInnerDeclarations.js:3:9 lint/nursery/noInnerDeclarations ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

   This function should be declared at the root of the enclosing function.
  
    1 │ function f() {
    2 │     if (test) {
  > 3 │         function g() {}
           ^^^^^^^^^^^^^^^
    4 │     }
    5 │ }
  
   The function is accessible in the whole body of the enclosing function.
    To avoid confusion, it should be declared at the root of the enclosing function.
  
function f() {
    if (test) {
        var x = 1;
    }
}
nursery/noInnerDeclarations.js:3:9 lint/nursery/noInnerDeclarations ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

   This var should be declared at the root of the enclosing function.
  
    1 │ function f() {
    2 │     if (test) {
  > 3 │         var x = 1;
           ^^^^^^^^^
    4 │     }
    5 │ }
  
   The var is accessible in the whole body of the enclosing function.
    To avoid confusion, it should be declared at the root of the enclosing function.
  

Valid

function f() { }
function f() {
    function g() {}
}
function f() {
    var x = 1;
}
function f() {
    if (test) {
        const g = function() {};
    }
}