Javascript.RU

Создать новую тему Ответ
 
Опции темы Искать в теме
  #1 (permalink)  
Старый 24.03.2014, 21:03
Новичок на форуме
Отправить личное сообщение для Temik2704 Посмотреть профиль Найти все сообщения от Temik2704
 
Регистрация: 24.03.2014
Сообщений: 2

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

Последний раз редактировалось Temik2704, 24.03.2014 в 22:04.
Ответить с цитированием
  #2 (permalink)  
Старый 24.03.2014, 22:16
sinistral
Посмотреть профиль Найти все сообщения от melky
 
Регистрация: 28.03.2011
Сообщений: 5,418

Сообщение от Temik2704
Что дает возврат функции?
функцию, которую можно вызвать, когда потребуется.

Сообщение от Temik2704
Здесь - то же самое,не понимаю зачем нужно вызывать функцию?
чтобы предотвратить переменные внутри функции от попадания в ГО (window) и предохраниться от конфликта с другими глобальными переменными

Сообщение от Temik2704
что есть такое x и что есть n?Откуда берутся?Особенно x?
n - переменная определена где-нибудь выше, а в кусок кода не включена. либо это глобальная window.n, либо переменная из замыкания

x - первый переданный аргумент. в данном случае это n.

Сообщение от Temik2704
Статьи за замыканиям читал много где,и на learn.javascript.ru и на хабре,и mozilla javascript reference - все равно не до конца понимаю.
поищи статьи на хабре. их там всего около 5 штук, но среди них есть одна годная и доходчивая... я ее что-то не могу найти
Ответить с цитированием
  #3 (permalink)  
Старый 24.03.2014, 22:33
Профессор
Отправить личное сообщение для skrudjmakdak Посмотреть профиль Найти все сообщения от skrudjmakdak
 
Регистрация: 27.04.2012
Сообщений: 1,410

приведу свой пример:

замыкания, это очень просто. сраду приведу рабочий пример. например есть несколько 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>
Ответить с цитированием
  #4 (permalink)  
Старый 24.03.2014, 22:51
Аватар для BETEPAH
Профессор
Отправить личное сообщение для BETEPAH Посмотреть профиль Найти все сообщения от BETEPAH
 
Регистрация: 23.06.2011
Сообщений: 1,165

Temik2704,
вставлю свои 5 центов. суть замыкания в данном случае - это возврат СЕЙЧАС функции, которую надо вызывать ПОТОМ (когда теперешний контекст уже потерян)
Ответить с цитированием
  #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;
}

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



Опции темы Искать в теме
Искать в теме:

Расширенный поиск


Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Всплытие событий или что то не так... Кирюха =) jQuery 6 30.03.2013 12:56
Вопрос по each() и перебору строк таблицы battrack jQuery 1 09.02.2012 14:30
вопрос про возможности JS для рисования и анимации macdack Библиотеки/Тулкиты/Фреймворки 3 15.07.2011 00:13
Вопрос по замыканиям Goodfella Общие вопросы Javascript 20 09.03.2011 01:21
Теоретический вопрос. gods33 (X)HTML/CSS 10 16.12.2010 23:49