Spec-Zone.ru › ESLint

no-use-before-define

Запрещает использование переменных до их определения

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

В ES6 привязки на уровне блока (let и const) создают «временную мёртвую зону», в которой при любой попытке обратиться к переменной до её объявления будет выброшено исключение ReferenceError.

Описание правила

Это правило выдаёт предупреждение, если обнаруживает ссылку на идентификатор, который ещё не был объявлен.

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

Открыть в Playground
/*eslint no-use-before-define: "error"*/

alert(a);
var a = 10;

f();
function f() {}

function g() {
    return b;
}
var b = 1;

{
    alert(c);
    let c = 1;
}

{
    class C extends C {}
}

{
    class C {
        static x = "foo";
        [C.x]() {}
    }
}

{
    const C = class {
        static x = C;
    }
}

{
    const C = class {
        static {
            C.x = "foo";
        }
    }
}

export { foo };
const foo = 1;

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

Открыть в Playground
/*eslint no-use-before-define: "error"*/

var a;
a = 10;
alert(a);

function f() {}
f(1);

var b = 1;
function g() {
    return b;
}

{
    let c;
    c++;
}

{
    class C {
        static x = C;
    }
}

{
    const C = class C {
        static x = C;
    }
}

{
    const C = class {
        x = C;
    }
}

{
    const C = class C {
        static {
            C.x = "foo";
        }
    }
}

const foo = 1;
export { foo };

Параметры

{
    "no-use-before-define": ["error", {
        "functions": true,
        "classes": true,
        "variables": true,
        "allowNamedExports": false,
        "enums": true,
        "typedefs": true,
        "ignoreTypeReferences": true
    }]
}
  • functions (boolean) — этот флаг определяет, проверяет ли правило объявления функций. Если значение равно true, правило выдаёт предупреждение при каждой ссылке на функцию до её объявления. В противном случае правило игнорирует такие ссылки. Объявления функций поднимаются, поэтому отключать этот параметр безопасно (обратите внимание: некоторые идиоматические шаблоны, например взаимная рекурсия, несовместимы с включением этого параметра). Значение по умолчанию — true.
  • classes (boolean) — этот флаг определяет, проверяет ли правило объявления классов во внешних областях видимости. Если значение равно true, правило выдаёт предупреждение при каждой ссылке на класс до его объявления. В противном случае правило игнорирует такие ссылки, если объявление находится во внешней области видимости функции. Объявления классов не поднимаются, поэтому отключать этот параметр может быть опасно. Значение по умолчанию — true.
  • variables (boolean) — этот флаг определяет, проверяет ли правило объявления переменных во внешних областях видимости. Если значение равно true, правило выдаёт предупреждение при каждой ссылке на переменную до её объявления. В противном случае правило игнорирует ссылку, если объявление находится во внешней области видимости, но сообщает о ссылке, если она находится в той же области видимости, что и объявление. Значение по умолчанию — true.
  • allowNamedExports (boolean) — если этому флагу задано значение true, правило всегда разрешает ссылки в объявлениях export {};. Такие ссылки безопасны, даже если переменные объявлены позже в коде. Значение по умолчанию — false.

Это правило также поддерживает синтаксис типов TypeScript. Следующие параметры включают проверку ссылок на объявления type, interface и enum:

  • enums (boolean) — если значение равно true, правило выдаёт предупреждение при каждой ссылке на enum до его определения. Значение по умолчанию — true.
  • typedefs (boolean) — если значение равно true, правило выдаёт предупреждение при каждой ссылке на тип alias или interface до его объявления. Если значение равно false, правило разрешает использовать типы alias и interface до их определения. Значение по умолчанию — true.
  • ignoreTypeReferences (boolean) — если значение равно true, правило игнорирует все ссылки на типы, например в аннотациях и утверждениях типов. Значение по умолчанию — true.

Это правило принимает строку "nofunc" в качестве параметра. "nofunc" — это то же самое, что и { "functions": false, "classes": true, "variables": true, "allowNamedExports": false, "enums": true, "typedefs": true, "ignoreTypeReferences": true }.

functions

Примеры правильного кода для параметра { "functions": false }:

Открыть в Playground
/*eslint no-use-before-define: ["error", { "functions": false }]*/

f();
function f() {}

Этот параметр разрешает ссылки на объявления функций. Сведения о функциональных выражениях и стрелочных функциях см. в описании параметра variables.

classes

Примеры неправильного кода для параметра { "classes": false }:

Открыть в Playground
/*eslint no-use-before-define: ["error", { "classes": false }]*/

new A();
class A {
}

{
    class C extends C {}
}

{
    class C extends D {}
    class D {}
}

{
    class C {
        static x = "foo";
        [C.x]() {}
    }
}

{
    class C {
        static {
            new D();
        }
    }
    class D {}
}

Примеры правильного кода для параметра { "classes": false }:

Открыть в Playground
/*eslint no-use-before-define: ["error", { "classes": false }]*/

function foo() {
    return new A();
}

class A {
}

variables

Примеры неправильного кода для параметра { "variables": false }:

Открыть в Playground
/*eslint no-use-before-define: ["error", { "variables": false }]*/

console.log(foo);
var foo = 1;

f();
const f = () => {};

g();
const g = function() {};

{
    const C = class {
        static x = C;
    }
}

{
    const C = class {
        static x = foo;
    }
    const foo = 1;
}

{
    class C {
        static {
            this.x = foo;
        }
    }
    const foo = 1;
}

Примеры правильного кода для параметра { "variables": false }:

Открыть в Playground
/*eslint no-use-before-define: ["error", { "variables": false }]*/

function baz() {
    console.log(foo);
}
var foo = 1;

const a = () => f();
function b() { return f(); }
const c = function() { return f(); }
const f = () => {};

const e = function() { return g(); }
const g = function() {}

{
    const C = class {
        x = foo;
    }
    const foo = 1;
}

allowNamedExports

Примеры правильного кода для параметра { "allowNamedExports": true }:

Открыть в Playground
/*eslint no-use-before-define: ["error", { "allowNamedExports": true }]*/

export { a, b, f, C };

const a = 1;

let b;

function f () {}

class C {}

Примеры неправильного кода для параметра { "allowNamedExports": true }:

Открыть в Playground
/*eslint no-use-before-define: ["error", { "allowNamedExports": true }]*/

export default a;
const a = 1;

const b = c;
export const c = 1;

export function foo() {
    return d;
}
const d = 1;

enums (только TypeScript)

Примеры неправильного кода для параметра { "enums": true }:

Открыть в Playground
/*eslint no-use-before-define: ["error", { "enums": true }]*/

const x = Foo.FOO;

enum Foo {
  FOO,
}

Примеры правильного кода для параметра { "enums": true }:

Открыть в Playground
/*eslint no-use-before-define: ["error", { "enums": true }]*/

enum Foo {
  FOO,
}

const x = Foo.FOO;

typedefs (только TypeScript)

Примеры неправильного кода для параметра { "enums": true } с параметром { "ignoreTypeReferences": false }:

Открыть в Playground
/*eslint no-use-before-define: ["error", { "typedefs": true, "ignoreTypeReferences": false }]*/

let myVar: StringOrNumber;

type StringOrNumber = string | number;

const x: Foo = {};

interface Foo {}

Примеры правильного кода для параметра { "typedefs": true } с параметром { "ignoreTypeReferences": false }:

Открыть в Playground
/*eslint no-use-before-define: ["error", { "typedefs": true, "ignoreTypeReferences": false }]*/

type StringOrNumber = string | number;

let myVar: StringOrNumber;

interface Foo {}

const x: Foo = {};

ignoreTypeReferences (только TypeScript)

Примеры неправильного кода для параметра { "ignoreTypeReferences": false }:

Открыть в Playground
/*eslint no-use-before-define: ["error", { "ignoreTypeReferences": false }]*/

let var1: StringOrNumber;

type StringOrNumber = string | number;

let var2: Enum;

enum Enum {}

Примеры правильного кода для параметра { "ignoreTypeReferences": false }:

Открыть в Playground
/*eslint no-use-before-define: ["error", { "ignoreTypeReferences": false }]*/

type StringOrNumber = string | number;

let myVar: StringOrNumber;

enum Enum {}

let var2: Enum;

Примеры правильного кода для параметра { "ignoreTypeReferences": false } с параметром { "typedefs": false }:

Открыть в Playground
/*eslint no-use-before-define: ["error", { "ignoreTypeReferences": false, "typedefs": false, }]*/

let myVar: StringOrNumber;

type StringOrNumber = string | number;

const x: Foo = {};

interface Foo {}

nofunc

Примеры неправильного кода для параметра "nofunc":

Открыть в Playground
/*eslint no-use-before-define: ["error", "nofunc"]*/

a();
var a = function() {};

console.log(foo);
var foo = 1;

function f() {
    return b;
}
var b = 1;

new A();
class A {
}

function g() {
    return new B();
}
class B {
}

export default bar;
const bar = 1;

export { baz };
const baz = 1;
Открыть в Playground
/*eslint no-use-before-define: ["error", "nofunc"]*/

function foo(): Foo {
	return Foo.FOO;
}
	
enum Foo {
	FOO,
}

Примеры правильного кода для параметра "nofunc":

Открыть в Playground
/*eslint no-use-before-define: ["error", "nofunc"]*/

f();
function f() {}

class A {
}
new A();

var a = 10;
alert(a);

const foo = 1;
export { foo };

const bar = 1;
export default bar;
Открыть в Playground
/*eslint no-use-before-define: ["error", "nofunc"]*/
	
enum Foo {
	FOO,
}

const foo = Foo.Foo;

Версия

Это правило добавлено в ESLint v0.0.9.

Ресурсы

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

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

Spec-Zone.ru

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