Вопрос по замыканиям
Добрый день!
Уже несколько дней пытаюсь понять замыкания в js,но пока не особо выходит. Подскажите пожалуйста: 1. Есть такой код http://jsfiddle.net/vnkuZ/ Мне интересно почему если в коде javascript вместо return function() { document.body.style.fontSize = size + 'px'; }; прописать return document.body.style.fontSize = size + 'px'; то скрипт становится нерабочим? Зачем возвращать функцию function() внутри функции makeSizer(size),когда можно сразу вернуть значение document.body.style.fontSize = size + 'px'?Почему это не работает? Что дает возврат функции? 2. http://jsfiddle.net/E5Aj6/ Здесь - то же самое,не понимаю зачем нужно вызывать функцию? Знаю то что без замыканий при таком скрипт,любой элемент будет отображать последнее значение массива. Но все равно не очень понимаю - что делает эта функция? Что нам это дает?Если не трудно,распишите поподробнее. function(x) { return function() { ... } }(n); Объясните пожалуйста также,в функции function(x) { }(n)что есть такое x и что есть n?Откуда берутся?Особенно x? P.S. Статьи за замыканиям читал много где,и на learn.javascript.ru и на хабре,и mozilla javascript reference - все равно не до конца понимаю. |
Цитата:
Цитата:
Цитата:
x - первый переданный аргумент. в данном случае это n. Цитата:
|
приведу свой пример:
замыкания, это очень просто. сраду приведу рабочий пример. например есть несколько div'ов и им надо повесить обработчики событий, причем у каждого из них должно быть какое то константное значение, смотрим первый пример: <html> <head> <title>example</title> </head> <body> <div color="red">1234567</div> <div color="blue">1234567</div> <div color="yellow">1234567</div> <script> //функция, которая будет вызываться при клике var click = function () { //функция берет из свойства color его значение. и изменяет цвет текста... var color = this.getAttribute('color'); this.style.color = color; } //Находим все div'ы и гоним цикл по этим элементам.. Array.prototype.forEach.call(document.querySelectorAll('div'), function (el) { //el - элемент массива //console.log(a); - можно посмотреть, что здесь находится... //присваиваем функцию событию.. el.onclick = click; }); </script> </body> </html> а теперь тоже самый пример, только с замыканием и без свойств color: <html> <head> <title>example</title> </head> <body> <div>1234567</div> <div>1234567</div> <div>1234567</div> <script> //функция, которая будет вызываться при клике var click = function (color) { return function () { //функция берет переменную color и изменяет ее цвет this.style.color = color; //переменная color запомнилась } } //Находим все div'ы var divs = document.querySelectorAll('div'); //когда мы вызываем функцию click то возвращается функция console.log(click("red")); //при этом переменная color сохраняется, когда ее использует другая функция. divs[0].onclick = click("red"); divs[1].onclick = click("blue"); divs[2].onclick = click("yellow"); </script> </body> </html> |
Temik2704,
вставлю свои 5 центов. суть замыкания в данном случае - это возврат СЕЙЧАС функции, которую надо вызывать ПОТОМ (когда теперешний контекст уже потерян) |
Суть замыкания не в том, что возвращается функция, а то, что переменные существующие на момент создания этой функции будут существовать пока на них есть ссылка из этой функции.
Вот, например в вашем первом примере можно изменить код функции для наглядности: 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; } В первоначальном виде там проиходит абсолютно то же самое, но функция создается и вызывается прямо в цикле. |
Часовой пояс GMT +3, время: 06:52. |