Ощущение неопределенности "Без тени"
У меня есть функция, которая проверяет текущий этап в последовательном потоке, основываясь на конкретной дисциплине, которая передается, и, согласно этому значению, назначает следующее значение в моем приложении Angular 2. Это выглядит примерно так:
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;
}
То, что я здесь делаю, возвращает значение "nextStageStep", потому что это то, что я буду потом, чтобы сделать правильный шаг шага.
Прямо сейчас, мой tslint подчеркивает каждое из событий "nextStageStep" с предупреждением "без теневых переменных". Если я удалю строку, где я инициализирую пустую строку, это предупреждение исчезнет, но затем я получаю сообщение об ошибке "Не могу найти nextStageStep", появляющееся в моей инструкции return.
В чем проблема с первоначальным предупреждением о затененной переменной, и есть ли альтернативный способ написать это, и/или я должен просто игнорировать предупреждение tslint в этой ситуации?
Ответы
Ответ 1
ЛИНТЕР жалуется, потому что вы переопределяете одну и ту же переменную несколько раз. Таким образом, заменяя те, которые содержатся в закрытии, содержащем его.
Вместо повторного использования он просто использует его:
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
Это связано с определением одной и той же переменной в разных областях. Вы определяете nextStageStep
пределах области функций и внутри каждого блока if. Один из вариантов - избавиться от объявлений переменных в блоках 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';
}
Вот хороший ресурс по теневым переменным http://eslint.org/docs/rules/no-shadow
Ответ 3
Вы повторно объявляете ту же переменную const nextStageStep
в каждом блоке if.
Juste заменить const nextStageStep = 'step 2';
с nextStageStep = 'step 2';
(и всех остальных случаях), и все будет в порядке.
Ответ 4
Добавить в: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/const
ES6 const BLOCK-SCOPED, таким образом:
{
const TAG='<yourIt>';
console.log(TAG);
}
{
const TAG = '<touchingBase NoImNOt="true">';
console.log(TAG);
}
console.log(TAG); // ERROR expected
AFAICT, это не случай затенения - каждая из констант правильно впирается в свои фигурные скобки.
Если мы не сможем повторно использовать имена переменных, мы закончим работу с нечитаемыми программами, которые неясны. а не сообщать.
Я считаю, что предупреждение ошибочно
Ответ 5
Обычно эта ошибка возникает, когда переменная в локальной области и переменная в содержащей области имеют одно и то же имя, происходит теневое копирование. Затенение делает невозможным доступ к переменной в содержащей области и скрывает, к какому значению относится идентификатор.
Обратитесь к этой статье за примерами кода, объясняющими это.
Ответ 6
Прежде всего, даже если вы продолжите с предупреждениями, ваша функция " getNextStageStep()
" всегда будет возвращать пустое значение,
-
Потому что " const
" является переменной области видимости, и
-
Он не поддерживает переопределение значения [Инициализированное значение не может быть изменено].
В return
переменной блок " nextStageStep
" содержит пустое значение строки, и внутренние блоки " nextStageStep
" переменные не будут маскировать или переопределить внешний блок " nextStageStep
" значение переменной.
Поэтому, когда вы возвращаете " nextStageStep
", он всегда будет возвращать пустую строку.
nextStageStep
действия переменных " nextStageStep
" внутренних блоков находится в том же диапазоне, если только блок, а здесь переменная " nextStageStep
" внешнего блока полностью отличается от переменных " nextStageStep
" внутреннего блока.
Поэтому, если вы хотите, чтобы ваш код работал, и если вы хотите использовать const
переменные, используйте несколько операторов return внутри блоков if.
Ниже приведен код, который я проверил и работает нормально. Вы можете использовать его по вашему требованию.
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'));
Но вместо написания этих многих операторов возврата лучше использовать переменную let
которая позволяет переопределить значение переменной. Для вашей проблемы я думаю, что решение @toskv подходит.