Форум программистов, компьютерный форум, киберфорум
JavaScript
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.83/6: Рейтинг темы: голосов - 6, средняя оценка - 4.83
1 / 1 / 1
Регистрация: 21.09.2015
Сообщений: 98

Как работает замыкание

07.06.2016, 20:44. Показов 1240. Ответов 4
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Когда использую 1 вариант цикла, то создается дополнительный индекс.
Во 2 варианте все хорошо.
Я не пойму момент с анонимной функцией, когда в конце ставится (i). Можете объяснить для чего это делается, как это работает, и что это за прием?
1) ===================================
JavaScript
1
2
3
4
5
for (var i = 0; i < el.length; i++) {
  el[i].addEventListener('change', function(){
    resetErrors(i);
  }, false);
}
2) ===================================
JavaScript
1
2
3
4
5
6
7
for (var i = 0; i < el.length; i++) {
  (function(i) {
    el[i].addEventListener('change', function(){
      resetErrors(i);
    }, false);
  } (i) );
}
===================================
0
Лучшие ответы (1)
IT_Exp
Эксперт
34794 / 4073 / 2104
Регистрация: 17.06.2006
Сообщений: 32,602
Блог
07.06.2016, 20:44
Ответы с готовыми решениями:

Не работает замыкание
Я новичок в JS , может чего не понял , но у меня не хочет работать замыкание: function testMegaFunc() { var topVar =...

Замыкание
Есть вопрос по коду function makeArmy() { var shooters = ; for (var i = 0; i &lt; 10;i++) { var shooter = function me() { ...

Замыкание
есть такой пример замыкания: function makeCounter() { var currentCount = 1; return function() { // (**) return...

4
 Аватар для Jetlag
111 / 49 / 20
Регистрация: 21.10.2013
Сообщений: 212
07.06.2016, 21:07
Сделайте так:
JavaScript
1
2
3
4
5
for (let i = 0; i < el.length; i++) { // block scope variable, es6
  el[i].addEventListener('change', function(){
    resetErrors(i);
  }, false);
}
Добавлено через 4 минуты

Как Вы снизу делать можно, так делают в старом стандарте. В прошлом году кончательно утвержден новый стандарт (а используется еще больше). В новом стандарте куча сахара, которы позволяет мне делать так, как я написал выше.

По вашему примеру:

Для чего это делается - чтобы создать отдельный скоуп, отдельную область видимости.
Область видимости для var переменных (то есть весь до-es6 javascript) определяется функцией, а не блоком, как во многих распространенных языках. Вместе с всплытием(hoisting) и замыканиям, это влечет за собой некоторые неинтуитивные вещи, как например вот эта.

Прием называется "оборачивание в анонимную самовызывающуюся функцию" или IIFE (Immediatly invoked function expression)
0
20 / 20 / 13
Регистрация: 22.11.2015
Сообщений: 109
07.06.2016, 21:15
1 вариант: событие обращается к глобальной переменой.
2 вариант: событие обращается к аргументу внешней функции.
Здесь что-то вроде
JavaScript
1
2
3
4
5
6
Array().forEach.call(el, function(el, i) {
  // создался аргумент с каким-то индексом элемента 
  el.addEventListener('change', function(){
    alert(i); // вызываем этот аргумент
  });
});
0
 Аватар для Jetlag
111 / 49 / 20
Регистрация: 21.10.2013
Сообщений: 212
07.06.2016, 21:29
Лучший ответ Сообщение было отмечено Leo Khan как решение

Решение

Теперь разберем почему код работает не так, как Вы ожидали.

JavaScript
1
2
3
4
5
6
7
8
function myScope(){
  console.log(i);
  for (var i = 0; i < el.length; i++) {
    el[i].addEventListener('change', function mySecondScope(){
      resetErrors(i);
    }, false);
  }
}
Для простоты обернем ваш код в функцию myScope, она просто обозначает область видимости, ничего больше. И вашу callback функцию назовем mySecondScope, она обозначает другую область видимости.
1). Программа смотрит значение i в момент выполнения функции, а не в момент назначения обработчика. И берет она это значение не из mySecondScope. В mySecondScope нет такого, зато есть в более старшей области видимости, в myScope.
2). Так вот, все ваши функции-обработчики mySecondScope которые вы насоздавали, оперируют одной и той же переменной i из myScope. Одной и той же. Одной и той же областью памяти.

Добавлено через 5 минут
Почему это исчезает во втором варианте?
JavaScript
1
2
3
4
5
6
7
8
9
function myScope(){
  for (var i = 0; i < el.length; i++) {
    (function IIEFScope(i) {
      el[i].addEventListener('change', function mySecondScope(){
        resetErrors(i);
      }, false);
    } (i) );
  }
}
MySecondScope опять лезет в более старший скоуп за переменной i. Вот только теперь, каждый обработчик лезет в свой скоуп. Где своя переменная i, а не одна на всех. То есть мы создали по сути n функций, в каждой из которых своя переменная i со своим значением.

Добавлено через 41 секунду
Уф, все, написал еще один ответ на вечный вопрос новичков, моя карма на сегодня чиста.
2
1 / 1 / 1
Регистрация: 21.09.2015
Сообщений: 98
07.06.2016, 21:38  [ТС]
Спасибо Вам за то, что так подробно разжевали! Теперь я понял в чем дело.
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
BasicMan
Эксперт
29316 / 5623 / 2384
Регистрация: 17.02.2009
Сообщений: 30,364
Блог
07.06.2016, 21:38
Помогаю со студенческими работами здесь

Замыкание
var a = 1; function b() { a = 10; return; function a() {} } b(); alert(a); Вот недавно читал статью про...

Замыкание на addEvent
Здравствуйте, подскажите пожалуйста, как правильно выполнить замыкания для передачи конретного инстанса в метод? Есть подобный код: ...

Замыкание и добавление нового пользователя
Приветствую всех, пару вопросов возникло Как правильно реализовать добавление нового персона (функция addPerson)? Я хочу хранить...

Замыкание
Дорбый, Например у нас есть обычный счетчик функция var c1; var c2; var c3; function c() {

Что такое замыкание?)
Ребят всем привет)Обьясните пожалучйста простым нормальным языком что такое замыкание и для чего они нужны?!Заранее спасибо


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
5
Ответ Создать тему
Новые блоги и статьи
Модель ЗдрввоСохранения 7: больше работников, больше ресурсов.
anaschu 08.04.2026
работников и заданий может быть сколько угодно, но настроено всё так, что используется пока что только 20%
Дальние перспективы сервера - слоя сети с космологическим дизайном интефейса карты и логики.
Hrethgir 07.04.2026
Дальнейшее ближайшее планирование вывело к размышлениям над дальними перспективами. И вот тут может быть даже будут нужны оценки специалистов, так как в дальних перспективах всё может очень сильно. . .
Горе от ума
kumehtar 07.04.2026
Эта мне ментальная установка, что вот прямо сейчас, мол, мне для полного счастья не хватает (нужное вписать), и когда я этого достигну - тогда и полный кайф. Одна из самых сильных ловушек на пути. . . .
Использование значений реквизитов справочника в документе, с определенными условиями и правами
Maks 07.04.2026
1. Контроль срока действия договора Алгоритм из решения ниже реализован на примере нетипового документа "ЗаявкаНаРаботу", разработанного в конфигурации КА2. Задача: уведомлять пользователя, если. . .
Доступность команды формы по условию
Maks 07.04.2026
Алгоритм из решения ниже реализован на примере нетипового документа "СписаниеМатериалов", разработанного в конфигурации КА2. Задача: сделать доступной кнопку (команда формы "ЗавершитьСписание") при. . .
Уведомление о неверно выбранном значении справочника
Maks 06.04.2026
Алгоритм из решения ниже реализован на примере нетипового документа "НарядПутевка", разработанного в конфигурации КА2. Задача: уведомлять пользователя, если в документе выбран неверный склад. . .
Установка Qt Creator для C и C++: ставим среду, CMake и MinGW без фреймворка Qt
8Observer8 05.04.2026
Среду разработки Qt Creator можно установить без фреймворка Qt. Есть отдельный репозиторий для этой среды: https:/ / github. com/ qt-creator/ qt-creator, где можно скачать установщик, на вкладке Releases:. . .
AkelPad-скрипты, структуры, и немного лирики..
testuser2 05.04.2026
Такая программа, как AkelPad существует уже давно, и также давно существуют скрипты под нее. Тем не менее, прога живет, периодически что-то не спеша дополняется, улучшается. Что меня в первую очередь. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru