Почему изменение const в цикле не вызывает ошибок и работает корректно?

На просторах Интернета встретил несколько функций наподобие этого кода:

const popupLinks = document.querySelectorAll(".popup-link");
if (popupLinks.length > 0){
    for (let i =0; i< popupLinks.length; ++i){
        const popupLink = popupLinks[i];
        popupLink.addEventListener("click", function(e){
        // делаем что-то при клике...
    });
    }
}

Интересует почему такой код не вызывает ошибок и даже предупреждений, ведь в строке:

const popupLink = popupLinks[i];

мы объявляем КОНСТАНТУ, константа меняться не может, а на второй и последующих итерациях цикла мы меняем ее. Как это работает? Мы же еще не вышли из цикла, соответственно идентификатор popupLink все еще занят значением, которое нельзя менять... и создавать новую по идее нельзя. Пока старая константа еще существует, вторую с тем же именем запрещено создавать. Тем не менее, такие функции спокойно работают. Почему?


Ответы (3 шт):

Автор решения: Aziz Umarov

Если посмотреть на это таким образом

const popupLinks = document.querySelectorAll(".popup-link");
if (popupLinks.length > 0){
    for (let i =0; i< popupLinks.length; ++i){
        somefunction(i);
    });
    }
}

function somefunction(var i) {
        const popupLink = popupLinks[i];
        popupLink.addEventListner("click", function(e){
        // делаем что-то при клике...
}

то думаю можно некоторые вопросы будут ясны с такой точки зрения

Попробую подобрать цитат отсюда и отсюда

Значение констант не может быть изменено новым присваиванием, а также не может быть переопределено. Константы (const) подчиняются области видимости уровня блока так же, как переменные, объявленные с использованием ключевого слова let.

Областью видимости переменных, объявленных ключевым словом let, является блок, в котором они объявлены, и все его подблоки.

отсюда блок цикла это {} и всё что там объявлено

→ Ссылка
Автор решения: MoloF

Когда вы объявляете константу в цикле, то при следующей итерации она создастся по новой. Поэтому ваша запись не вызывает никаких ошибок и все отлично работает.

Если вы перенесёте переменную popupLink на один уровень выше, то вы получите соответствующую ошибку, её решением будет просто изменить const на let

Блоки кода задают область видимости констант, а константы, определенные на вложенных блоках кода, скрывают внешние константы с тем же именем

Источник


В вашем коде была ошибка в названии метода: addEventListner, вместо него следовало бы написать addEventListener

const popupLinks = document.querySelectorAll(".popup-link");

if (popupLinks.length > 0){
    for (let i =0; i< popupLinks.length; ++i){
        const popupLink = popupLinks[i];
        popupLink.addEventListener("click", function(e){
            // делаем что-то при клике...
            console.log('click');
        });
    }
}
<div class="popup-link">Popup Link</div>


На каждой итерации переменной присваивается значение другого свойства. переменная может быть объявлена ​​с помощью const, let или var.

Источник

const popupLinks = document.querySelectorAll(".popup-link");

for (const popupLink of popupLinks) {
    popupLink.addEventListener("click", () => console.log('click'));
}
<div class="popup-link">Popup Link</div>
<div class="popup-link">Popup Link</div>

→ Ссылка
Автор решения: Grundy

модификатор const гарантирует только то, что переменной можно будет присвоить значение только один раз.

В приведенном коде, значение присваивается один раз

const popupLink = popupLinks[i];

следовательно все, в соответствии с требованиями.

На каждой итерации цикла создается своя собственная константа доступная только внутри текущей итерации.

→ Ссылка