Показать сообщение отдельно
  #5 (permalink)  
Старый 25.03.2014, 04:12
Профессор
Отправить личное сообщение для jsnb Посмотреть профиль Найти все сообщения от jsnb
 
Регистрация: 15.03.2014
Сообщений: 561

Суть замыкания не в том, что возвращается функция, а то, что переменные существующие на момент создания этой функции будут существовать пока на них есть ссылка из этой функции.
Вот, например в вашем первом примере можно изменить код функции для наглядности:
function makeSizer(size) {
  var fnSize = size;
  return function() {
    document.body.style.fontSize = fnSize + 'px';
  };
}

Т.е. у нас есть в функции makeSizer локальная переменная fnSize к которой обращается возвращаемая функция.
При вызове makeSizer:
var size12 = makeSizer(12);

переменной fnSize будет присвоено значение 12 и в переменную size12 попадет созданная в makeSizer функция. Т.о. переменная size12 - это ссылка на новую созданную функцию. Т.е. произошедшее аналогично было бы такой записи:
var fnSize = 12;
var size12 = function() {
  document.body.style.fontSize = fnSize + 'px';
};

Так вот, фишка в том, что fnSize несморя на то, что она локальная переменная функции makeSizer и вроде как должна быть недоступна после выполнения функции makeSizer, всё равно доступна из возвращаемой функции. Т.е. вместе с созданной функцией сохранилось и ее окружение. При следующем вызове makeSizer создается новая функция и переменной fnSize присваивается новое значение (14) и опять же эта переменная сохраняется вместе с созданной функцией и будет через нее доступна. Т.е. суть замыкания в том, что возвращаемая функция сохраняется с ее окружением и может с ним работать.

Во втором примере тоже используется этот трюк с сохранением окружения, но в не совсем явном виде. Можно видоизменить его так:
var elem = document.getElementsByTagName('a');

function createNewFunction(x) {
  var localVar = x; 

  return function() {
    alert(localVar);
    return false;
  }
}

for (var n = 0; n < elem.length; n++) {
  //n - счетчик цикла, будет меняться на каждой итерации цикла
  //соответственно в newFunc на каждой итерации будет новая функция
  //и localVar для кадой новой функции будет равно n
  var newFunc = createNewFunction(n);

  //записываем в обработчик ссылки новую функцию
  elem[n].onclick = newFunc;
}

В первоначальном виде там проиходит абсолютно то же самое, но функция создается и вызывается прямо в цикле.
Ответить с цитированием