Цель closures
состоит в том, чтобы просто сохранить государство; отсюда и название closure
- оно закрывается над государством. Для простоты дальнейшего объяснения я буду использовать Javascript.
Обычно у вас есть функция
function sayHello(){
var txt="Hello";
return txt;
}
где область действия переменной (ей) связана с этой функцией. Таким образом, после выполнения переменная txt
выходит из области видимости. Нет способа получить доступ или использовать его после завершения функции.
Замыкания - это языковые конструкции, которые позволяют, как было сказано ранее, сохранять состояние переменных и таким образом продлевать область видимости.
Это может быть полезно в разных случаях. Одним из вариантов использования является построение функций более высокого порядка .
В математике и информатике функция высшего порядка (также функциональная форма, функционал или функтор) - это функция, которая выполняет хотя бы одно из следующих действий: 1
- принимает одну или несколько функций в качестве входа
- выводит функцию
Простой, но, правда, не слишком полезный пример:
makeadder=function(a){
return function(b){
return a+b;
}
}
add5=makeadder(5);
console.log(add5(10));
Вы определяете функцию makedadder
, которая принимает один параметр в качестве входных данных и возвращает функцию . Существует внешняя функция function(a){}
и внутренняя. function(b){}{}
Кроме того, вы определяете (неявно) другую функцию add5
в результате вызова функции более высокого порядка makeadder
. makeadder(5)
возвращает анонимную ( внутреннюю ) функцию, которая, в свою очередь, принимает 1 параметр и возвращает сумму параметра внешней функции и параметра внутренней функции.
Трик в том, что при возвращении на внутреннюю функцию, которая делает фактическое добавление, объем параметра внешней функции ( a
) сохраняются. add5
помнит , что параметр a
был 5
.
Или показать хотя бы один полезный пример:
makeTag=function(openTag, closeTag){
return function(content){
return openTag +content +closeTag;
}
}
table=makeTag("<table>","</table>")
tr=makeTag("<tr>", "</tr>");
td=makeTag("<td>","</td>");
console.log(table(tr(td("I am a Row"))));
Другим распространенным случаем использования является так называемое выражение вызываемой функции IIFE =. В javascript очень распространено подделывать закрытые переменные-члены. Это делается с помощью функции, которая создает частную область видимости = closure
, потому что она сразу после вызова определения вызывается. Структура есть function(){}()
. Обратите внимание на скобки ()
после определения. Это позволяет использовать его для создания объекта с раскрытием шаблона модуля . Хитрость заключается в создании области действия и возвращении объекта, который имеет доступ к этой области после выполнения IIFE.
Пример Адди выглядит так:
var myRevealingModule = (function () {
var privateVar = "Ben Cherry",
publicVar = "Hey there!";
function privateFunction() {
console.log( "Name:" + privateVar );
}
function publicSetName( strName ) {
privateVar = strName;
}
function publicGetName() {
privateFunction();
}
// Reveal public pointers to
// private functions and properties
return {
setName: publicSetName,
greeting: publicVar,
getName: publicGetName
};
})();
myRevealingModule.setName( "Paul Kinlan" );
Возвращаемый объект имеет ссылки на функции (например publicSetName
), которые в свою очередь имеют доступ к «закрытым» переменным privateVar
.
Но это более особые случаи использования Javascript.
Какую конкретную задачу будет выполнять программист, которая лучше всего подходит для закрытия?
Для этого есть несколько причин. Можно подумать, что это естественно для него, поскольку он следует функциональной парадигме . Или в Javascript: это просто необходимость полагаться на замыкания, чтобы обойти некоторые странности языка.