版本

no-shadow

禁止變數宣告遮蔽外部作用域中宣告的變數

遮蔽是指區域變數與其包含作用域中的變數共用相同名稱的過程。例如

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

在這種情況下,b() 內部的變數 a 遮蔽了全域作用域中的變數 a。這可能會在閱讀程式碼時造成混淆,並且無法存取全域變數。

規則詳情

此規則旨在消除被遮蔽的變數宣告。

此規則的 錯誤 程式碼範例

在 Playground 中開啟
/*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 } 選項的 錯誤 程式碼範例

在 Playground 中開啟
/*eslint no-shadow: ["error", { "builtinGlobals": true }]*/

function foo() {
    var Object = 0;
}

hoist

hoist 選項有三種設定

  • functions (預設) - 報告在外部函式定義之前發生的遮蔽。
  • all - 報告在外部變數/函式定義之前發生的所有遮蔽。
  • never - 永遠不報告在外部變數/函式定義之前發生的遮蔽。

hoist: functions

預設 { "hoist": "functions" } 選項的 錯誤 程式碼範例

在 Playground 中開啟
/*eslint no-shadow: ["error", { "hoist": "functions" }]*/

if (true) {
    let b = 6;
}

function b() {}

雖然 if 陳述式中的 let b 在外部作用域的函式宣告之前,但這是錯誤的。

預設 { "hoist": "functions" } 選項的 正確 程式碼範例

在 Playground 中開啟
/*eslint no-shadow: ["error", { "hoist": "functions" }]*/

if (true) {
    let a = 3;
}

let a = 5;

因為 if 陳述式中的 let a 在外部作用域的變數宣告之前,所以這是正確的。

hoist: all

{ "hoist": "all" } 選項的 錯誤 程式碼範例

在 Playground 中開啟
/*eslint no-shadow: ["error", { "hoist": "all" }]*/

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

let a = 5;
function b() {}

hoist: never

{ "hoist": "never" } 選項的 正確 程式碼範例

在 Playground 中開啟
/*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"] } 選項的 正確 程式碼範例

在 Playground 中開啟
/*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" } 選項的 錯誤 程式碼範例

在 Playground 中開啟
/*eslint no-shadow: ["error", { "ignoreOnInitialization": true }]*/

var x = x => x;

因為遮蔽變數 x 將會遮蔽已經初始化的被遮蔽變數 x

{ "ignoreOnInitialization": true } 選項的 正確 程式碼範例

在 Playground 中開啟
/*eslint no-shadow: ["error", { "ignoreOnInitialization": true }]*/

var x = foo(x => x)

var y = (y => y)()

回呼函式的基本原理是假設它們會在初始化期間被呼叫,以便在將使用遮蔽變數時,被遮蔽的變數尚未初始化。

版本

此規則在 ESLint v0.0.9 中引入。

延伸閱讀

資源

變更語言