Spec-Zone.ru › ESLint

no-inner-declarations

Запрещает объявления переменных или function во вложенных блоках

В JavaScript до ES6 объявление функции допускается только на верхнем уровне программы или в теле другой функции, хотя парсеры иногда ошибочно принимают их в других местах. Это относится только к объявлениям функций; именованные или анонимные функциональные выражения могут встречаться везде, где допустимо выражение.

// Good
function doSomething() { }

// Bad
if (test) {
    function doSomethingElse () { }
}

function anotherThing() {
    var fn;

    if (test) {

        // Good
        fn = function expression() { };

        // Bad
        function declaration() { }
    }
}

В ES6 функции уровня блока (функции, объявленные внутри блока) ограничены областью видимости блока, в котором они объявлены, и за пределами этой области видимости их нельзя получить и вызвать, но только если код находится в строгом режиме (код с тегом "use strict" или модули ESM). В нестрогом режиме к ним можно получить доступ и вызвать их за пределами области видимости блока.

"use strict";

if (test) {
    function doSomething () { }

    doSomething(); // no error
}

doSomething(); // error

Объявление переменной разрешено везде, где может находиться инструкция, даже глубоко внутри других блоков. Это часто нежелательно из-за поднятия переменных, а перенос объявлений на верхний уровень программы или тела функции может повысить ясность кода. Обратите внимание, что привязки уровня блока (let, const) не поднимаются, поэтому это правило на них не распространяется.

// Good
var foo = 42;

// Good
if (foo) {
    let bar1;
}

// Bad
while (test) {
    var bar2;
}

function doSomething() {
    // Good
    var baz = true;

    // Bad
    if (baz) {
        var quux;
    }
}

Подробное описание правила

Это правило требует, чтобы объявления функций и, при необходимости, объявления переменных находились на верхнем уровне программы, на верхнем уровне тела функции или на верхнем уровне тела статического блока класса.

Параметры

Это правило принимает строковый параметр и параметр-объект:

  • "functions" (по умолчанию) запрещает объявления function во вложенных блоках
  • "both" запрещает объявления function и var во вложенных блоках
  • { blockScopedFunctions: "allow" } (по умолчанию) этот параметр разрешает объявления function во вложенных блоках, если код находится в строгом режиме (код с тегом "use strict" или модули ESM) и для languageOptions.ecmaVersion установлено значение 2015 или выше. Этот параметр можно отключить, установив значение "disallow".

functions

Примеры некорректного кода для этого правила с параметром "functions" по умолчанию:

Открыть в Playground
/*eslint no-inner-declarations: "error"*/

// script, non-strict code

if (test) {
    function doSomething() { }
}

function doSomethingElse() {
    if (test) {
        function doAnotherThing() { }
    }
}

if (foo) function f(){}

Примеры корректного кода для этого правила с параметром "functions" по умолчанию:

Открыть в Playground
/*eslint no-inner-declarations: "error"*/

function doSomething() { }

function doSomethingElse() {
    function doAnotherThing() { }
}

function doSomethingElse() {
    "use strict";

    if (test) {
        function doAnotherThing() { }
    }
}

class C {
    static {
        function doSomething() { }
    }
}

if (test) {
    asyncCall(id, function (err, data) { });
}

var fn;
if (test) {
    fn = function fnExpression() { };
}

if (foo) var a;

both

Примеры некорректного кода для этого правила с параметром "both":

Открыть в Playground
/*eslint no-inner-declarations: ["error", "both"]*/

if (test) {
    var foo = 42;
}

function doAnotherThing() {
    if (test) {
        var bar = 81;
    }
}

if (foo) var a;

if (foo) function f(){}

class C {
    static {
        if (test) {
            var something;
        }
    }
}

Примеры корректного кода для этого правила с параметром "both":

Открыть в Playground
/*eslint no-inner-declarations: ["error", "both"]*/

var bar = 42;

if (test) {
    let baz = 43;
}

function doAnotherThing() {
    var baz = 81;
}

class C {
    static {
        var something;
    }
}

blockScopedFunctions

Пример некорректного кода для этого правила с параметром { blockScopedFunctions: "disallow" } и ecmaVersion: 2015:

Открыть в Playground
/*eslint no-inner-declarations: ["error", "functions", { blockScopedFunctions: "disallow" }]*/

// non-strict code

if (test) {
    function doSomething() { }
}

function doSomething() {
    if (test) {
        function doSomethingElse() { }
    }
}

// strict code

function foo() {
    "use strict";

    if (test) {
        function bar() { }
    }
}

Пример корректного кода для этого правила с параметром { blockScopedFunctions: "disallow" } и ecmaVersion: 2015:

Открыть в Playground
/*eslint no-inner-declarations: ["error", "functions", { blockScopedFunctions: "disallow" }]*/

function doSomething() { }

function doSomething() {
    function doSomethingElse() { }
}

Пример корректного кода для этого правила с параметром { blockScopedFunctions: "allow" } и ecmaVersion: 2015:

Открыть в Playground
/*eslint no-inner-declarations: ["error", "functions", { blockScopedFunctions: "allow" }]*/

"use strict";

if (test) {
    function doSomething() { }
}

function doSomething() {
    if (test) {
        function doSomethingElse() { }
    }
}

// OR

function foo() {
    "use strict";

    if (test) {
        function bar() { }
    }
}

ESM modules и объявления, и выражения both class всегда находятся в строгом режиме.

Открыть в Playground
/*eslint no-inner-declarations: ["error", "functions", { blockScopedFunctions: "allow" }]*/

if (test) {
    function doSomething() { }
}

function doSomethingElse() {
    if (test) {
        function doAnotherThing() { }
    }
}

class Some {
    static {
        if (test) {
            function doSomething() { }
        }
    }
}

const C = class {
    static {
        if (test) {
            function doSomething() { }
        }
    }
}

Когда не следует использовать это правило

По умолчанию это правило запрещает внутренние объявления функций только в контекстах, где их поведение не определено и, следовательно, непоследовательно (среды до ES6), либо применяются устаревшие семантические правила (код в нестрогом режиме). Если ваш код предназначен для сред до ES6 или не работает в строгом режиме, следует включить это правило, чтобы предотвратить неожиданное поведение.

В средах ES6+ и в коде строгого режима поведение внутренних объявлений функций определено и единообразно: они всегда ограничены областью видимости блока. Если ваш код предназначен только для сред ES6+ и работает в строгом режиме (модули ES или код с директивами "use strict"), включать это правило не нужно, если только вы не хотите запретить внутренние функции из стилистических соображений; в таком случае включите это правило с параметром blockScopedFunctions: "disallow".

Отключите проверку объявлений переменных при использовании block-scoped-var или если объявления переменных во вложенных блоках приемлемы, несмотря на поднятие.

Версия

Это правило появилось в ESLint v0.6.0.

Ресурсы

  • Исходный код правила
  • Исходный код тестов

© OpenJS Foundation and other contributors
Licensed under the MIT License.
https://eslint.org/docs/latest/rules/no-inner-declarations

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API