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" по умолчанию:
/*eslint no-inner-declarations: "error"*/
// script, non-strict code
if (test) {
}
function doSomethingElse() {
if (test) {
}
}
if (foo)
Примеры правильного кода для этого правила с параметром "functions" по умолчанию:
/*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":
/*eslint no-inner-declarations: ["error", "both"]*/
if (test) {
}
function doAnotherThing() {
if (test) {
}
}
if (foo)
if (foo)
class C {
static {
if (test) {
}
}
}
Примеры правильного кода для этого правила с параметром "both":
/*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:
/*eslint no-inner-declarations: ["error", "functions", { blockScopedFunctions: "disallow" }]*/
// non-strict code
if (test) {
}
function doSomething() {
if (test) {
}
}
// strict code
function foo() {
"use strict";
if (test) {
}
}
Пример правильного кода для этого правила с параметром { blockScopedFunctions: "disallow" } со значением ecmaVersion: 2015:
/*eslint no-inner-declarations: ["error", "functions", { blockScopedFunctions: "disallow" }]*/
function doSomething() { }
function doSomething() {
function doSomethingElse() { }
}
Пример правильного кода для этого правила с параметром { blockScopedFunctions: "allow" } со значением ecmaVersion: 2015:
/*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 объявления и выражения всегда находятся в строгом режиме.
/*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