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 中,块级绑定(let 和 const)引入了一个“暂时性死区”,在变量声明之前尝试访问该变量会抛出 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
}]
}
functions(boolean)- 这个标志决定规则是否检查函数声明。如果设置为true,规则会在每次引用函数而该函数尚未声明时发出警告。否则,规则将忽略这些引用。函数声明会被提升,因此禁用此选项是安全的(注意,一些惯用模式,例如 互相递归,与启用此选项不兼容)。默认值为true。classes(boolean)- 这个标志决定规则是否检查上层作用域的类声明。如果该值为true,规则会对类声明前的每一个引用发出警告。否则,只要声明在上层函数作用域中,规则会忽略这些引用。类声明不会被提升,所以禁用此选项可能是危险的。默认值为true。variables(boolean)- 此标志决定规则是否检查上层作用域中的变量声明。如果设置为true,规则将在变量声明之前对每次对该变量的引用发出警告。否则,如果声明在上层作用域中,规则会忽略该引用,但如果引用与声明在相同作用域中,则仍会报告该引用。默认值为true。allowNamedExports(boolean)- 如果此标志设置为true,则规则总是允许在export {};声明中引用。这些引用即使在代码中变量稍后声明也安全。默认值为false。
此规则还支持 TypeScript 类型语法。以下选项启用对 type、interface 和 enum 声明引用的检查:
🌐 This rule additionally supports TypeScript type syntax. The following options enable checking for the references to type, interface and enum declarations:
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 } 相同。
🌐 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 中引入。