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
    }]
}
  • functions(boolean) - 此标志决定规则是否检查函数声明。如果是 true,则规则会在函数声明之前对每个函数引用触发警告。否则,规则将忽略这些引用。函数声明会被提升,因此可以安全地禁用此选项(请注意,某些惯用模式,例如 相互递归,与启用此选项不兼容)。默认为 true

    ¥functions (boolean) - This flag determines whether or not the rule checks function declarations. If this is true, the rule warns on every reference to a function before the function declaration. Otherwise, the rule ignores those references. Function declarations are hoisted, so it’s safe to disable this option (note that some idiomatic patterns, such as mutual recursion, are incompatible with enabling this option). Default is true.

  • classes(boolean) - 此标志决定规则是否检查上层作用域的类声明。如果是 true,则该规则会在类声明之前对每个类的引用触发警告。否则,规则将忽略此类引用,前提是声明位于上层函数作用域内。类声明不会被提升,因此禁用此选项可能很危险。默认为 true

    ¥classes (boolean) - This flag determines whether or not the rule checks class declarations of upper scopes. If this is true, the rule warns on every reference to a class before the class declaration. Otherwise, the rule ignores such references, provided the declaration is in an upper function scope. Class declarations are not hoisted, so it might be dangerous to disable this option. Default is true.

  • variables(boolean) - 此标志确定规则是否检查上层作用域中的变量声明。如果是 true,则规则会在变量声明之前对每个变量引用触发警告。否则,如果声明在上层范围内,则规则忽略引用,而如果引用与声明在同一范围内,则仍报告引用。默认为 true

    ¥variables (boolean) - This flag determines whether or not the rule checks variable declarations in upper scopes. If this is true, the rule warns on every reference to a variable before the variable declaration. Otherwise, the rule ignores a reference if the declaration is in an upper scope, while still reporting the reference if it’s in the same scope as the declaration. Default is true.

  • allowNamedExports(boolean) - 如果此标志设置为 true,则该规则始终允许在 export {}; 声明中进行引用。即使稍后在代码中声明变量,这些引用也是安全的。默认为 false

    ¥allowNamedExports (boolean) - If this flag is set to true, the rule always allows references in export {}; declarations. These references are safe even if the variables are declared later in the code. Default is false.

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

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

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;

版本

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

资源