Index

no-use-before-define

禁止在定义变量之前使用变量

在 JavaScript 中,在 ES6 之前,变量和函数的声明会被提升到作用域的顶部,因此在代码中可以在正式声明之前使用标识符。这可能会让人困惑,有些人认为最好总是在使用变量和函数之前先声明它们。

🌐 In JavaScript, prior to ES6, variable and function declarations are hoisted to the top of a scope, so it’s possible to use identifiers before their formal declarations in code. This can be confusing and some believe it is best to always declare variables and functions before using them.

在 ES6 中,块级绑定(letconst)引入了一个“暂时性死区”,在变量声明之前尝试访问该变量会抛出 ReferenceError

🌐 In ES6, block-level bindings (let and const) introduce a “temporal dead zone” where a ReferenceError will be thrown with any attempt to access the variable before its declaration.

规则详情

🌐 Rule Details

当遇到对尚未声明的标识符的引用时,此规则将触发警告。

🌐 This rule will warn when it encounters a reference to an identifier that has not yet been declared.

此规则的错误代码示例:

🌐 Examples of incorrect code for this rule:

在线运行
/*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;

符合此规则的正确代码示例:

🌐 Examples of correct code for this rule:

在线运行
/*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 };

选项

🌐 Options

{
    "no-use-before-define": ["error", {
        "functions": true,
        "classes": true,
        "variables": true,
        "allowNamedExports": false,
        "enums": true,
        "typedefs": true,
        "ignoreTypeReferences": true
    }]
}
  • functionsboolean)- 这个标志决定规则是否检查函数声明。如果设置为 true,规则会在每次引用函数而该函数尚未声明时发出警告。否则,规则将忽略这些引用。函数声明会被提升,因此禁用此选项是安全的(注意,一些惯用模式,例如 互相递归,与启用此选项不兼容)。默认值为 true
  • classesboolean)- 这个标志决定规则是否检查上层作用域的类声明。如果该值为 true,规则会对类声明前的每一个引用发出警告。否则,只要声明在上层函数作用域中,规则会忽略这些引用。类声明不会被提升,所以禁用此选项可能是危险的。默认值为 true
  • variablesboolean)- 此标志决定规则是否检查上层作用域中的变量声明。如果设置为 true,规则将在变量声明之前对每次对该变量的引用发出警告。否则,如果声明在上层作用域中,规则会忽略该引用,但如果引用与声明在相同作用域中,则仍会报告该引用。默认值为 true
  • allowNamedExportsboolean)- 如果此标志设置为 true,则规则总是允许在 export {}; 声明中引用。这些引用即使在代码中变量稍后声明也安全。默认值为 false

此规则还支持 TypeScript 类型语法。以下选项启用对 typeinterfaceenum 声明引用的检查:

🌐 This rule additionally supports TypeScript type syntax. The following options enable checking for the references to type, interface and enum declarations:

  • enumsboolean)- 如果是 true,规则会警告在 enum 定义之前对其的每次引用。默认是 true
  • typedefsboolean)- 如果是 true,此规则会警告在声明之前对类型 aliasinterface 的每次引用。如果是 false,该规则允许在类型 aliasinterface 被定义之前使用它们。默认值是 true
  • ignoreTypeReferencesboolean)- 如果是 true,规则将忽略所有类型引用,例如类型注解和断言。默认是 true

此规则接受 "nofunc" 字符串作为选项。 "nofunc"{ "functions": false, "classes": true, "variables": true, "allowNamedExports": false, "enums": true, "typedefs": true, "ignoreTypeReferences": true } 相同。

🌐 This rule accepts "nofunc" string as an option. "nofunc" is the same as { "functions": false, "classes": true, "variables": true, "allowNamedExports": false, "enums": true, "typedefs": true, "ignoreTypeReferences": true }.

functions

适用于 { "functions": false } 选项的正确代码示例:

🌐 Examples of correct code for the { "functions": false } option:

在线运行
/*eslint no-use-before-define: ["error", { "functions": false }]*/

f();
function f() {}

此选项允许引用函数声明。对于函数表达式和箭头函数,请参阅 variables 选项。

🌐 This option allows references to function declarations. For function expressions and arrow functions, please see the variables option.

classes

针对 { "classes": false } 选项的错误代码示例:

🌐 Examples of incorrect code for the { "classes": false } option:

在线运行
/*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 } 选项的正确代码示例:

🌐 Examples of correct code for the { "classes": false } option:

在线运行
/*eslint no-use-before-define: ["error", { "classes": false }]*/

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

class A {
}

variables

针对 { "variables": false } 选项的错误代码示例:

🌐 Examples of incorrect code for the { "variables": false } option:

在线运行
/*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 } 选项的正确代码示例:

🌐 Examples of correct code for the { "variables": false } option:

在线运行
/*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 } 选项的正确代码示例:

🌐 Examples of correct code for the { "allowNamedExports": true } option:

在线运行
/*eslint no-use-before-define: ["error", { "allowNamedExports": true }]*/

export { a, b, f, C };

const a = 1;

let b;

function f () {}

class C {}

针对 { "allowNamedExports": true } 选项的错误代码示例:

🌐 Examples of incorrect code for the { "allowNamedExports": true } option:

在线运行
/*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;

枚举(仅限 TypeScript)

🌐 enums (TypeScript only)

针对 { "enums": true } 选项的错误代码示例:

🌐 Examples of incorrect code for the { "enums": true } option:

在线运行
/*eslint no-use-before-define: ["error", { "enums": true }]*/

const x = Foo.FOO;

enum Foo {
  FOO,
}

适用于 { "enums": true } 选项的正确代码示例:

🌐 Examples of correct code for the { "enums": true } option:

在线运行
/*eslint no-use-before-define: ["error", { "enums": true }]*/

enum Foo {
  FOO,
}

const x = Foo.FOO;

typedefs(仅限 TypeScript)

🌐 typedefs (TypeScript only)

{ “ignoreTypeReferences”: false } 选项下 { "enums": true }错误代码示例:

🌐 Examples of incorrect code for the { "enums": true } with { "ignoreTypeReferences": false } option:

在线运行
/*eslint no-use-before-define: ["error", { "typedefs": true, "ignoreTypeReferences": false }]*/

let myVar: StringOrNumber;

type StringOrNumber = string | number;

const x: Foo = {};

interface Foo {}

{ “ignoreTypeReferences”: false } 选项下 { "typedefs": true }正确代码示例:

🌐 Examples of correct code for the { "typedefs": true } with { "ignoreTypeReferences": false } option:

在线运行
/*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 (TypeScript only)

针对 { "ignoreTypeReferences": false } 选项的错误代码示例:

🌐 Examples of incorrect code for the { "ignoreTypeReferences": false } option:

在线运行
/*eslint no-use-before-define: ["error", { "ignoreTypeReferences": false }]*/

let var1: StringOrNumber;

type StringOrNumber = string | number;

let var2: Enum;

enum Enum {}

适用于 { "ignoreTypeReferences": false } 选项的正确代码示例:

🌐 Examples of correct code for the { "ignoreTypeReferences": false } option:

在线运行
/*eslint no-use-before-define: ["error", { "ignoreTypeReferences": false }]*/

type StringOrNumber = string | number;

let myVar: StringOrNumber;

enum Enum {}

let var2: Enum;

{ “typedefs”: false } 选项下 { "ignoreTypeReferences": false }正确代码示例:

🌐 Examples of correct code for the { "ignoreTypeReferences": false } with { "typedefs": false } option:

在线运行
/*eslint no-use-before-define: ["error", { "ignoreTypeReferences": false, "typedefs": false, }]*/

let myVar: StringOrNumber;

type StringOrNumber = string | number;

const x: Foo = {};

interface Foo {}

nofunc

针对 "nofunc" 选项的错误代码示例:

🌐 Examples of incorrect code for the "nofunc" option:

在线运行
/*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;
在线运行
/*eslint no-use-before-define: ["error", "nofunc"]*/

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

适用于 "nofunc" 选项的正确代码示例:

🌐 Examples of correct code for the "nofunc" option:

在线运行
/*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;
在线运行
/*eslint no-use-before-define: ["error", "nofunc"]*/
	
enum Foo {
	FOO,
}

const foo = Foo.Foo;

版本

此规则是在 ESLint v0.0.9 中引入。

资源