Проблема с областью действия с циклами for в Javascript

Я понимаю, что это, вероятно, классифицируется как дубликат, однако я подробно прочитал этот вопрос и ответы, но все еще не могу понять это.

У меня есть этот код, но в функции «focus» «i» всегда равно 2 (значение pageSearchInput.length), и я хочу, чтобы оно было 0,1 соответственно в каждом цикле.

Я понимаю, что это проблема области видимости, но я не могу понять, как исправить этот без, просто используя let.

Если бы кто-нибудь мог объяснить, как это работает, я был бы очень благодарен.

for (i = 0; i < pageSearchInput.length; i++) {

    pageSearchInput[i].addEventListener("focus", function(){

        pageSearchContainer[i].style.outline = "4px solid #ffcc33";
        pageSearchButton[i].style.backgroundColor = "#008920";
        pageSearchButton[i].style.border = "1px solid #008920";

    });

}

Я не уверен, если честно, но, может быть, определить var i вне цикла?

WhiteMaple 09.08.2018 13:50

@ArthurWietzorek он уже может быть определен вне цикла?

OliverRadini 09.08.2018 13:51

Почему не стал бы вы просто используете let? Это одна из основных причин существования let.

Cerbrus 09.08.2018 13:54

Потому что он не поддерживается в IE10 или более ранних версиях, а веб-сайт, который я создаю, нуждается в этом. Этот вопрос был отмечен как повторяющийся для вопроса «разрешить», когда я прямо сказал, что не хочу использовать его в вопросе. Слегка доволен

paddyfields 09.08.2018 13:56

Это потому, что i увеличивается до pageSearchInput.length - 1 и цикл не завершается. Затем в какой-то момент в будущем выполняется прослушиватель событий, используя значение i * в этот момент времени . Wrap the code inside in a function that takes a parameter and pass in i`, и он будет выполняться, как ожидалось.

Reinstate Monica Cellio 09.08.2018 13:56

@paddyfields: я обновил цель. Есть миллиард вопросов, которые обсуждают эту тему. Я не в восторге от триггера. Может быть, вы разместили этот вопрос?

Cerbrus 09.08.2018 13:57

Не особо, я новичок в javascript, и не всегда легко узнать терминологию, которую нужно искать. Спасибо за ссылку, это явно то, что мне нужно было прочитать.

paddyfields 09.08.2018 14:02

Пожалуйста. Но в качестве примечания, в следующий раз, пожалуйста, воздержитесь от называния кого-то «счастливым». Это не очень хорошо. Если вы не согласны, не стесняйтесь спрашивать пользователя, почему он сделал то, что сделал.

Cerbrus 09.08.2018 14:02

Конечно, еще раз спасибо.

paddyfields 09.08.2018 14:05
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
1
9
46
5

Ответы 5

Вы должны использовать ключевое слово let, чтобы сохранить значение i в области для loop.

for (let i = 0; i < pageSearchInput.length; i++) {

Другой способ - использовать Выражение немедленно вызываемой функции

(function(i){
   pageSearchInput[i].addEventListener("focus", function(){

   });
})(i);

Спасибо, но в вопросе я сказал, что не хочу использовать let. Код должен быть совместимым с IE.

paddyfields 09.08.2018 13:49

@paddyfields - вот для чего нужны транспилеры.

Jared Smith 09.08.2018 13:50

@paddyfields, обновляю свой ответ.

Mihai Alexandru-Ionut 09.08.2018 13:50

Просто сделайте i параметром функции, передайте его и верните функцию, которая обрабатывает событие:

for (i = 0; i < pageSearchInput.length; i++) {

    pageSearchInput[i].addEventListener("focus", (function(i){
      return function() {
        pageSearchContainer[i].style.outline = "4px solid #ffcc33";
        pageSearchButton[i].style.backgroundColor = "#008920";
        pageSearchButton[i].style.border = "1px solid #008920";
      };
    })(i));

}

Если вы не хотите использовать let, вам следует создать функцию упаковки.

for (i = 0; i < pageSearchInput.length; i++) {


    pageSearchInput[i].addEventListener("focus", function(){
        return (function(i) {
            pageSearchContainer[i].style.outline = "4px solid #ffcc33";
            pageSearchButton[i].style.backgroundColor = "#008920";
            pageSearchButton[i].style.border = "1px solid #008920";
        })(i);
    });

}

Вы можете использовать IIFE (выражение немедленно вызываемой функции)

(function () {
  statements
})();

It is a design pattern which is also known as a Self-Executing Anonymous Function and contains two major parts. The first is the anonymous function with lexical scope enclosed within the Grouping Operator (). This prevents accessing variables within the IIFE idiom as well as polluting the global scope.

The second part creates the immediately executing function expression () through which the JavaScript engine will directly interpret the function.

С IIFE ваш код должен быть:

for (i = 0; i < pageSearchInput.length; i++) {
  (function(i){
     pageSearchInput[i].addEventListener("focus", function(){

       pageSearchContainer[i].style.outline = "4px solid #ffcc33";
       pageSearchButton[i].style.backgroundColor = "#008920";
       pageSearchButton[i].style.border = "1px solid #008920";

    });
  })(i);
}

Вы можете попробовать использовать IIFE, чтобы решить вашу проблему, связанную с областью видимости.

for (i = 0; i < pageSearchInput.length; i++) {
   (function(j){
    return pageSearchInput[j].addEventListener("focus", function(){

        pageSearchContainer[j].style.outline = "4px solid #ffcc33";
        pageSearchButton[j].style.backgroundColor = "#008920";
        pageSearchButton[j].style.border = "1px solid #008920";

    })
  }(i))

}

Для подробностей найдите объяснение в этом посте. http://learnwebtechs.com/2018/05/11/understanding-javascript-closures-with-example

Другие вопросы по теме