Показать сообщение отдельно
  #13 (permalink)  
Старый 31.08.2012, 00:58
Аватар для Aetae
Тлен
Отправить личное сообщение для Aetae Посмотреть профиль Найти все сообщения от Aetae
 
Регистрация: 02.01.2010
Сообщений: 6,585

Что там разбирать, всё элементарно.
function doublingDecorator(f) {
  return function() {
    return 2*f.apply(this, arguments); // (*)
  };
}

// Использование:

function sum(a, b) {
  return a + b;
}

sum = doublingDecorator(sum);

alert( sum(1,2) ); // 6
alert( sum(2,3) ); // 10


Вызываем: doublingDecorator(sum)

function doublingDecorator(f) {
	//,,,
}

В данном случае f = sum,
т.е. условно
f = function(a, b) {
	return a + b;
}
Собсно эта f находится в scope(области видимости) текущего вызова данной функции.

//...
return function() {
	return 2*f.apply(this, arguments); // (*)
}
это по сути то же самое что:
function temp() {
	return 2*f.apply(this, arguments); // (*)
}
return temp
просто не создаётся лишних переменных, а идёт возврат на ходу созданной функции.

И поскольку функция, создаваемая внутри другой функции, видит все внутренние переменные, она замыкает их все на себя, тем самым сохраняя их в доступности даже после завершения работы материнской функции.

Последним действием:
sum = doublingDecorator(sum);
затирается первоначальная ссылка на sum, т.е. sum = temp. В простом случае это заставило бы сборщик мусора стереть саму память о функции на которую раньше ссылалась sum, но у нас сохранилась ещё одна ссылка на оную - переменная f, замкнутая внутри новосозданной функции temp и, соответственно, вполне работоспособная.


f.apply(this, arguments);
.apply же просто вызывает нашу функцию f с теми аргументами, что переданы в temp(+подменяет this, но это отдельная тема).
В данном же случае можно было поступить и так:
function temp(a,b) {
	return 2*f(a, b); // (*)
}
но изначальный вариант универсальнее, ибо не привязан к конкретной функции sum и может использоваться с другими.


Ещё небольшой примерчик пользы замыканий:
function act( num ){
	return {
		minus : function( n ){ return num - n },
		plus : function( n ){ return num + n },
	}
}

a = 10;
a = act(a);

alert( a.plus( 3 ) ); //13
alert( a.minus( -1 ) ); //12


Это работает, т.к. обе функции видят одну и ту же переменную num, что при вызове стала равной a,
и, т.к. act уже отработала, эта переменная больше никому недоступна.


Не знаю, помог ли я или ещё сильнее запутал, но пускай будет.)
__________________
29375, 35

Последний раз редактировалось Aetae, 31.08.2012 в 01:04.
Ответить с цитированием