Making Sense of 'No Shadowed Variable' tsl

2019-01-25 03:46发布

问题:

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. 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.

Right now, my tslint is underlining each of the "nextStageStep" variable occurrences with the warning "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.

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?

回答1:

The linter complains because you are redefining the same variable multiple times. 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;
}


回答2:

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. One option is to get rid of the variable declarations in the if blocks

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



回答3:

You are re-declaring the same variable const nextStageStep in each if block.

Juste replace const nextStageStep = 'step 2'; with nextStageStep = 'step 2'; (and all the other if cases) and it'll be all right.



回答4:

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

ES6 const is BLOCK-SCOPED, thus:


{
    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.

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



回答5:

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.