Ситуация: мы помним, что в JavaScript есть области видимости переменной. Это значит, например, что если мы объявляем переменную внутри функции, то из основной программы она недоступна — её видит только функция. А наоборот, если объявить в основной программе и использовать в функции, — всё нормально, так можно.
Ещё мы помним, что в программировании бывают циклы — когда что-то делается много раз. Для работы циклу нужна переменная-счётчик (обычно для счётчика используют букву i). В цикле for своя область видимости.
Зная это, мы сначала делаем цикл for с внутренней переменной i. Когда цикл заканчивается и переменная перестаёт быть видимой, создаём новую константу i. Проблем быть не должно: цикл закончился, имя переменной освободилось, и мы можем её использовать дальше:
for (var i = 0; i < 10; i++) {
/* ... */
}
const i = 3;
console.log('Привет!')
Но после запуска мы почему-то получаем ошибку:
❌ SyntaxError: Identifier 'i' has already been declared
Что это значит: браузер увидел, что мы пытаемся создать переменную или константу с тем же именем, что мы уже использовали для другой переменной.
Почему так произошло: дело в том, что в JavaScript есть такой эффект — var hosting, или сохранение последнего значения переменной. Из-за этого значение переменной остаётся в памяти вместе с именем даже после выхода из блока видимости.
Например, мы можем объявить внутри функции вторую переменную с тем же именем, что и глобальная, и ошибки не будет — у них разная область видимости:
var x = 1;
if (x === 1) {
var x = 2;
}
Но если мы изменим значение локальной переменной, а потом обратимся к глобальной переменной x, то увидим, что оно изменилось:
var x = 1;
if (x === 1) {
var x = 2;
console.log(x);
// выведет 2
}
console.log(x);
// тоже выведет 2, хотя в глобальной переменной до этого было 1
Так происходит как раз из-за эффекта var hosting — компьютер просто берёт из памяти последнее значение такой переменной и делает вид, что так и должно быть.
Как исправить ошибку SyntaxError: Identifier has already been declared
Это самая простая ошибка для исправления в JavaScript: достаточно взять другое имя для переменной, которого ещё не было в коде, и ошибка исчезнет.
В нашем случае мы заменим i в основном коде на X — это имя для переменной мы в коде ещё не использовали, поэтому ошибки уже не будет:
for (var i = 0; i < 10; i++) {
/* ... */
}
const X = 3;
console.log('Привет!')