O objetivo de closuresé simplesmente preservar o estado; daí o nome closure- ele fecha sobre o estado. Para facilitar a explicação, usarei Javascript.
Normalmente você tem uma função
function sayHello(){
var txt="Hello";
return txt;
}
onde o escopo da (s) variável (s) está vinculado a essa função. Então, após a execução, a variável txtsai do escopo. Não há como acessá-lo ou usá-lo após a conclusão da execução da função.
Os fechamentos são construtos de linguagem, que permitem - como dito anteriormente - preservar o estado das variáveis e prolongar o escopo.
Isso pode ser útil em diferentes casos. Um caso de uso é a construção de funções de ordem superior .
Em matemática e ciências da computação, uma função de ordem superior (também forma funcional, funcional ou functor) é uma função que executa pelo menos um dos seguintes procedimentos: 1
- assume uma ou mais funções como entrada
- gera uma função
Um exemplo simples, mas admitidamente não muito útil, é:
makeadder=function(a){
return function(b){
return a+b;
}
}
add5=makeadder(5);
console.log(add5(10));
Você define uma função makedadder, que recebe um parâmetro como entrada e retorna uma função . Existe uma função externafunction(a){} e uma interna function(b){}{} . Além disso, você define (implicitamente) outra função add5como resultado de chamar a função de ordem superior makeadder. makeadder(5)retorna uma função anônima ( interna ), que, por sua vez, recebe 1 parâmetro e retorna a soma do parâmetro da função externa e o parâmetro da função interna .
O truque é que, ao retornar a função interna , que faz a adição real, o escopo do parâmetro da função externa ( a) é preservado. add5 lembra , que o parâmetro afoi 5.
Ou para mostrar um exemplo pelo menos de alguma forma útil:
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"))));
Outro caso de uso comum é a chamada expressão de função IIFE = chamada imediatamente. É muito comum em javascript falsificar variáveis de membros particulares. Isso é feito por meio de uma função, que cria um escopo privado = closure, porque é imediatamente após a definição da invocação. A estrutura é function(){}(). Observe os colchetes ()após a definição. Isso torna possível usá-lo para criação de objetos com padrão de módulo revelador . O truque é criar um escopo e retornar um objeto, que tenha acesso a esse escopo após a execução do IIFE.
O exemplo de Addi é assim:
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" );
O objeto retornado tem referências a funções (por exemplo publicSetName), que por sua vez têm acesso a variáveis "particulares" privateVar.
Mas esses são casos de uso mais especiais para Javascript.
Que tarefa específica um programador executaria que poderia ser melhor atendida por um fechamento?
Há várias razões para isso. Pode-se dizer que isso é natural para ele, pois ele segue um paradigma funcional . Ou em Javascript: é mera necessidade contar com fechamentos para contornar algumas peculiaridades da linguagem.