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" по умолчанию:

Открыть в 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":

Открыть в 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 и оба 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