no-shadow

禁止在外部作用域中声明的隐藏变量的变量声明

影子化是局部变量与其包含范围内的变量共享相同名称的过程。例如:

¥Shadowing is the process by which a local variable shares the same name as a variable in its containing scope. For example:

var a = 3;
function b() {
    var a = 10;
}

在这种情况下,b() 内部的变量 a 将在全局作用域内隐藏变量 a。这可能会在阅读代码时造成混乱,并且无法访问全局变量。

¥In this case, the variable a inside of b() is shadowing the variable a in the global scope. This can cause confusion while reading the code and it’s impossible to access the global variable.

规则详情

¥Rule Details

该规则旨在消除阴影变量声明。

¥This rule aims to eliminate shadowed variable declarations.

此规则的错误代码示例:

¥Examples of incorrect code for this rule:

在线运行
/*eslint no-shadow: "error"*/

var a = 3;
function b() {
    var a = 10;
}

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

function d(a) {
    a = 10;
}
d(a);

if (true) {
    let a = 5;
}

选项

¥Options

此规则采用一个选项,即对象,具有属性 "builtinGlobals""hoist""allow""ignoreOnInitialization"

¥This rule takes one option, an object, with properties "builtinGlobals", "hoist", "allow" and "ignoreOnInitialization".

{
    "no-shadow": ["error", { "builtinGlobals": false, "hoist": "functions", "allow": [], "ignoreOnInitialization": false }]
}

builtinGlobals

builtinGlobals 选项默认为 false。如果它是 true,则该规则会阻止隐藏内置全局变量:ObjectArrayNumber 等等。

¥The builtinGlobals option is false by default. If it is true, the rule prevents shadowing of built-in global variables: Object, Array, Number, and so on.

{ "builtinGlobals": true } 选项的错误代码示例:

¥Examples of incorrect code for the { "builtinGlobals": true } option:

在线运行
/*eslint no-shadow: ["error", { "builtinGlobals": true }]*/

function foo() {
    var Object = 0;
}

hoist

hoist 选项具有三个设置:

¥The hoist option has three settings:

  • functions(默认情况下) - 在定义外部函数之前报告阴影。

    ¥functions (by default) - reports shadowing before the outer functions are defined.

  • all - 在定义外部变量/函数之前报告所有阴影。

    ¥all - reports all shadowing before the outer variables/functions are defined.

  • never - 在定义外部变量/函数之前,永远不要报告阴影。

    ¥never - never report shadowing before the outer variables/functions are defined.

提升:functions

¥hoist: functions

默认 { "hoist": "functions" } 选项的错误代码示例:

¥Examples of incorrect code for the default { "hoist": "functions" } option:

在线运行
/*eslint no-shadow: ["error", { "hoist": "functions" }]*/

if (true) {
    let b = 6;
}

function b() {}

虽然 if 语句中的 let b 在外部作用域的函数声明之前,但它是不正确的。

¥Although let b in the if statement is before the function declaration in the outer scope, it is incorrect.

默认 { "hoist": "functions" } 选项的正确代码示例:

¥Examples of correct code for the default { "hoist": "functions" } option:

在线运行
/*eslint no-shadow: ["error", { "hoist": "functions" }]*/

if (true) {
    let a = 3;
}

let a = 5;

因为 if 语句中的 let a 在外部作用域的变量声明之前,所以是正确的。

¥Because let a in the if statement is before the variable declaration in the outer scope, it is correct.

提升:all

¥hoist: all

{ "hoist": "all" } 选项的错误代码示例:

¥Examples of incorrect code for the { "hoist": "all" } option:

在线运行
/*eslint no-shadow: ["error", { "hoist": "all" }]*/

if (true) {
    let a = 3;
    let b = 6;
}

let a = 5;
function b() {}

提升:never

¥hoist: never

{ "hoist": "never" } 选项的正确代码示例:

¥Examples of correct code for the { "hoist": "never" } option:

在线运行
/*eslint no-shadow: ["error", { "hoist": "never" }]*/

if (true) {
    let a = 3;
    let b = 6;
}

let a = 5;
function b() {}

因为 if 语句中的 let alet b 在外部作用域的声明之前,所以它们是正确的。

¥Because let a and let b in the if statement are before the declarations in the outer scope, they are correct.

allow

allow 选项是一个标识符名称数组,允许对其进行遮蔽。例如,"resolve""reject""done""cb"

¥The allow option is an array of identifier names for which shadowing is allowed. For example, "resolve", "reject", "done", "cb".

{ "allow": ["done"] } 选项的正确代码示例:

¥Examples of correct code for the { "allow": ["done"] } option:

在线运行
/*eslint no-shadow: ["error", { "allow": ["done"] }]*/

import async from 'async';

function foo(done) {
  async.map([1, 2], function (e, done) {
    done(null, e * 2)
  }, done);
}

foo(function (err, result) {
  console.log({ err, result });
});

ignoreOnInitialization

ignoreOnInitialization 选项默认为 false。如果它是 true,那么当阴影变量可能仍未初始化时,它会阻止在其初始化程序中报告变量的阴影。

¥The ignoreOnInitialization option is false by default. If it is true, it prevents reporting shadowing of variables in their initializers when the shadowed variable is presumably still uninitialized.

阴影变量必须在左侧。阴影变量必须位于右侧并在回调函数或 IIFE 中声明。

¥The shadowed variable must be on the left side. The shadowing variable must be on the right side and declared in a callback function or in an IIFE.

{ "ignoreOnInitialization": "true" } 选项的错误代码示例:

¥Examples of incorrect code for the { "ignoreOnInitialization": "true" } option:

在线运行
/*eslint no-shadow: ["error", { "ignoreOnInitialization": true }]*/

var x = x => x;

因为阴影变量 x 将阴影已经初始化的阴影变量 x

¥Because the shadowing variable x will shadow the already initialized shadowed variable x.

{ "ignoreOnInitialization": true } 选项的正确代码示例:

¥Examples of correct code for the { "ignoreOnInitialization": true } option:

在线运行
/*eslint no-shadow: ["error", { "ignoreOnInitialization": true }]*/

var x = foo(x => x)

var y = (y => y)()

回调函数的基本原理是假设它们将在初始化期间被调用,因此在使用阴影变量时,阴影变量尚未初始化。

¥The rationale for callback functions is the assumption that they will be called during the initialization, so that at the time when the shadowing variable will be used, the shadowed variable has not yet been initialized.

版本

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

进阶读物

资源