Вопрос по замыканиям
Добрый день!
Уже несколько дней пытаюсь понять замыкания в 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, время: 20:49. |