版本

no-shadow

禁止变量声明覆盖外部作用域中声明的变量

阴影化是指局部变量与包含作用域中的变量共享相同名称的过程。例如

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

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

规则详情

此规则旨在消除被覆盖的变量声明。

此规则的错误代码示例

在游乐场中打开
/*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;
}

选项

此规则接受一个选项,一个对象,包含属性"builtinGlobals""hoist""allow""ignoreOnInitialization"

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

builtinGlobals

builtinGlobals选项默认为false。如果为true,则规则会阻止覆盖内置全局变量:ObjectArrayNumber等。

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

在游乐场中打开
/*eslint no-shadow: ["error", { "builtinGlobals": true }]*/

function foo() {
    var Object = 0;
}

hoist

hoist选项有三种设置

  • functions(默认) - 报告在外部函数定义之前发生的覆盖。
  • all - 报告在外部变量/函数定义之前发生的所有覆盖。
  • never - 从不报告在外部变量/函数定义之前发生的覆盖。

hoist: functions

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

在游乐场中打开
/*eslint no-shadow: ["error", { "hoist": "functions" }]*/

if (true) {
    let b = 6;
}

function b() {}

尽管if语句中的let b在外部作用域的函数声明之前,但它是错误的。

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

在游乐场中打开
/*eslint no-shadow: ["error", { "hoist": "functions" }]*/

if (true) {
    let a = 3;
}

let a = 5;

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

hoist: all

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

在游乐场中打开
/*eslint no-shadow: ["error", { "hoist": "all" }]*/

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

let a = 5;
function b() {}

hoist: never

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

在游乐场中打开
/*eslint no-shadow: ["error", { "hoist": "never" }]*/

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

let a = 5;
function b() {}

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

allow

allow选项是一个标识符名称数组,允许覆盖这些名称。例如,"resolve""reject""done""cb"

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

在游乐场中打开
/*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,则它会阻止在初始化程序中报告变量的覆盖,此时被覆盖的变量可能尚未初始化。

被覆盖的变量必须位于左侧。覆盖变量必须位于右侧,并在回调函数或 IIFE 中声明。

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

在游乐场中打开
/*eslint no-shadow: ["error", { "ignoreOnInitialization": true }]*/

var x = x => x;

因为覆盖变量x将覆盖已初始化的被覆盖变量x

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

在游乐场中打开
/*eslint no-shadow: ["error", { "ignoreOnInitialization": true }]*/

var x = foo(x => x)

var y = (y => y)()

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

版本

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

进一步阅读

资源

更改语言