简体   繁体   English

理解“无阴影变量”tslint 警告

[英]Making Sense of 'No Shadowed Variable' tslint Warning

I have a function that checks for the current stage in a sequential stream, based on a particular discipline that is passed in, and, according to that value, assigns the next value in my Angular 2 app.我有一个函数,它根据传入的特定学科检查顺序流中的当前阶段,并根据该值在我的 Angular 2 应用程序中分配下一个值。 It looks something like this:它看起来像这样:

private getNextStageStep(currentDisciplineSelected) {
    const nextStageStep = '';
        if (this.stageForDiscipline(this.currentDisciplineSelected) === 'step 1') {
            const nextStageStep = 'step 2';
        } else if (this.stageForDiscipline(this.currentDisciplineSelected) === 'step 2') {
            const nextStageStep = 'step 3';
        } else if (this.stageForDiscipline(this.currentDisciplineSelected) === 'step 3') {
            const nextStageStep = 'step 4';
        } else if (this.stageForDiscipline(this.currentDisciplineSelected) === 'step 4') {
            const nextStageStep = 'step 5';
        } else if (this.stageForDiscipline(this.currentDisciplineSelected) === 'step 5') {
            const nextStageStep = 'step 6';
    }
    return nextStageStep;
}

What I'm doing here is returning the value of nextStageStep , because that's what I'll be then passing in order for the correct stage step to happen.我在这里做的是返回nextStageStep的值,因为这是我将要传递的值,以便正确的阶段步骤发生。

Right now, my tslint is underlining each of the nextStageStep variable occurrences with the warning no shadowed variables .现在,我的 tslint 正在强调每个nextStageStep变量出现的警告no shadowed variables nextStageStep no shadowed variables If I remove the line where I initialize to an empty string that warning goes away, but then I get the error, Cannot find nextStageStep showing up in my return statement.如果我删除了我初始化为警告消失的空字符串的行,但随后出现错误, Cannot find nextStageStep在我的返回语句中Cannot find nextStageStep

What is the issue with the original shadowed variable warning, and is there an alternative way to write this, and/or should I simply ignore the tslint warning in this situation?原始阴影变量警告有什么问题,有没有其他方法可以写这个,和/或在这种情况下我应该简单地忽略 tslint 警告?

The linter complains because you are redefining the same variable multiple times. linter 抱怨是因为您多次重新定义同一个变量。 Thus replacing the ones in the closure containing it.因此替换包含它的闭包中的那些。

Instead of redeclaring it just use it:而不是重新声明它只是使用它:

private getNextStageStep(currentDisciplineSelected) {
    let nextStageStep = '';
        if (this.stageForDiscipline(this.currentDisciplineSelected) === 'step 1') {
             nextStageStep = 'step 2';
        } else if (this.stageForDiscipline(this.currentDisciplineSelected) === 'step 2') {
             nextStageStep = 'step 3';
        } else if (this.stageForDiscipline(this.currentDisciplineSelected) === 'step 3') {
             nextStageStep = 'step 4';
        } else if (this.stageForDiscipline(this.currentDisciplineSelected) === 'step 4') {
             nextStageStep = 'step 5';
        } else if (this.stageForDiscipline(this.currentDisciplineSelected) === 'step 5') {
             nextStageStep = 'step 6';
    }
    return nextStageStep;
}

This has to do with defining the same variable in different scopes.这与在不同范围内定义相同的变量有关。 You are defining nextStageStep within the function scope & also within each if block.您正在函数范围内以及每个 if 块中定义nextStageStep One option is to get rid of the variable declarations in the if blocks一种选择是去掉 if 块中的变量声明

if (this.stageForDiscipline(this.currentDisciplineSelected) === 'step 1') {
   nextStageStep = 'step 2';
} else if (this.stageForDiscipline(this.currentDisciplineSelected) === 'step 2') {
   nextStageStep = 'step 3';
} else if (this.stageForDiscipline(this.currentDisciplineSelected) === 'step 3') {
   nextStageStep = 'step 4';
} else if (this.stageForDiscipline(this.currentDisciplineSelected) === 'step 4') {
   nextStageStep = 'step 5';
} else if (this.stageForDiscipline(this.currentDisciplineSelected) === 'step 5') {
   nextStageStep = 'step 6';
}

Here is a good resource on shadowed variables http://eslint.org/docs/rules/no-shadow这是一个关于阴影变量的好资源http://eslint.org/docs/rules/no-shadow

Addording to : https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/const添加到: https : //developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/const

ES6 const is BLOCK-SCOPED, thus: ES6 const 是块范围的,因此:


{
    const TAG='<yourIt>';
    console.log(TAG);
 }

 {
  const TAG = '<touchingBase NoImNOt="true">';
  console.log(TAG);
 }

 console.log(TAG);  // ERROR expected

AFAICT, this is NOT a case of shadowing - each of the constants is soped correctly within its braces. AFAICT,这不是阴影的情况 - 每个常量都在其大括号内正确地进行了调整。

If we cannot re-use variable names, we will wind up with unreadable programs that obscure.如果我们不能重用变量名,我们最终会得到一些晦涩难懂的程序。 rather than inform.而不是通知。

I believe the warning is wrong-headed我相信警告是错误的

You are re-declaring the same variable const nextStageStep in each if block.您正在每个 if 块中重新声明相同的变量const nextStageStep

Juste replace const nextStageStep = 'step 2'; Juste replace const nextStageStep = 'step 2'; with nextStageStep = 'step 2';nextStageStep = 'step 2'; (and all the other if cases) and it'll be all right. (以及所有其他情况),一切都会好起来的。

In general this error occurs When a variable in a local scope and a variable in the containing scope have the same name, shadowing occurs.通常,当局部作用域中的变量和包含作用域中的变量具有相同名称时,会发生此错误。 Shadowing makes it impossible to access the variable in the containing scope and obscures to what value an identifier actually refers阴影使得无法访问包含范围内的变量,并掩盖了标识符实际引用的值

Refer to this article for code samples explaining this.请参阅 本文以获取解释此 内容的代码示例。

First of all, even if you proceed with the warnings, your function " getNextStageStep() " will always return the empty value,首先,即使您继续执行警告,您的函数“ getNextStageStep() ”也将始终返回空值,

  • Because " const " a is block-scoped variable, and因为“ const ” a 是块范围的变量,并且

  • It does not supports re-defining of value [Initialized value cannot be changed].不支持重新定义值[初始化的值不能改变]。

In return block variable " nextStageStep " contains empty string value, and inner blocks " nextStageStep " variables will not mask or override the outer block's " nextStageStep " variable value. return块变量“ nextStageStep ”包含空字符串值,内部块“ nextStageStep ”变量不会屏蔽或覆盖外部块的“ nextStageStep ”变量值。

So whenever you return " nextStageStep ", it will always return empty string.因此,每当您返回“ nextStageStep ”时,它将始终返回空字符串。

Inner blocks " nextStageStep " variables scope is within that if block only and here outer block " nextStageStep " variable is completely different from inner block " nextStageStep " variables.内部块“ nextStageStep ”变量范围仅在if块内,这里外部块“ nextStageStep ”变量与内部块“ nextStageStep ”变量完全不同。

So if you want your code to work and if you must want to use const variables, then use multiple return statements within if blocks.因此,如果您希望您的代码能够正常工作,并且必须使用const变量,那么请在 if 块中使用多个 return 语句。

Below is the code I checked and working fine.下面是我检查的代码并且工作正常。 you can use it according to your requirement.您可以根据您的要求使用它。

function  getNextStageStep(currentDisciplineSelected) {
    const nextStageStep = '';
    if (currentDisciplineSelected === 'step 1') {
        const nextStageStep = 'step 2';
        return nextStageStep;
    } else if (currentDisciplineSelected === 'step 2') {
        const nextStageStep = 'step 3';
        return nextStageStep;
    } else if (currentDisciplineSelected === 'step 3') {
        const nextStageStep = 'step 4';
        return nextStageStep;
    } else if (currentDisciplineSelected === 'step 4') {
        const nextStageStep = 'step 5';
        return nextStageStep;
    } else if (currentDisciplineSelected === 'step 5') {
        const nextStageStep = 'step 6';
        return nextStageStep;
    }
    return nextStageStep;
}
console.log(getNextStageStep('step 1'));

But instead writing these many return statements better to use let variable which allows you to re-define the variable value.但是,最好使用let变量编写这么多 return 语句,它允许您重新定义变量值。 For your problem I think @toskv solution is suitable.对于您的问题,我认为@toskv解决方案是合适的。

Locate and open your tslint.json file and set the following setting to false找到并打开您的 tslint.json 文件并将以下设置设置为 false

 "no-shadowed-variable": false,

When using visual studio, a restart of visual studio might be required.使用 Visual Studio 时,可能需要重新启动 Visual Studio。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM