Guia simplificado para ajudar você a entender closures em JavaScript #iniciante

Tempo de leitura: 6 minutos

Closures em JavaScript são um daqueles conceitos que muitos lutam para entender. No post a seguir, explicarei em termos claros o que é um closure e direcionarei o ponto de partida de cada um, usando exemplos de código simples.

O que é um closure?

Um closure é um recurso em JavaScript no qual uma função interna tem acesso às variáveis da função externa em uma cadeia de escopo.

O closure tem três cadeias de escopo:

  • Tem acesso ao seu próprio escopo – variáveis definidas entre suas chaves;
  • Tem acesso às variáveis da função externa;
  • Tem acesso às variáveis globais;

Mas o que realmente é um closure?

Um Closure simples

Vejamos um exemplo simples de closure em JavaScript:

function outer() {
   var b = 10;
   function inner() {

         var a = 20; 
         console.log(a+b);
    }
   return inner;
}

Aqui nós temos duas funções:

  • Uma função externa outer que tem uma variável b e retorna a função inner ;
  • Uma função interna inner que tem uma variável chamada a que acessa a variável b presente na função outer que está dentro de seu corpo de função.

O escopo da variável b é limitado à função outer , e o escopo da variável a é limitado à função inner.

Vamos invocar agora a função outer e armazenar em uma variável X e logo após invoca-la novamente e armazená-la na variável Y.

function outer() {
   var b = 10;
   function inner() {

         var a = 20; 
         console.log(a+b);
    }
   return inner;
}
var X = outer(); //outer() invocado pela primeira vez
var Y = outer(); //outer() invocado pela segunda vez

Vamos ver passo a passo o que acontece quando a função outer é invocada pela primeira vez:

  1. A variável b é criada, seu escopo é limitado à função outer() e seu valor é definido como 10.
  2. A próxima linha é uma declaração de função, então nada acontece neste ponto.
  3. Na última linha, return inner procura uma variável chamada inner, descobre que esta variável inner é uma função e, portanto, retorna o corpo inteiro da função inner. Observe que a instrução de return não executa a função inner ,uma função é executada apenas quando seguida por (), mas a instrução return retorna o corpo inteiro da função.
  4. O conteúdo retornado pela instrução de return é armazenado em X. Assim, o X armazenará o seguinte:
 var a=20; 
console.log(a+b); 
}
  1. A função outer() termina a execução e todas as variáveis dentro do escopo de outer() agora não existem mais.

Esta última parte é importante para entendermos que quando uma função completa sua execução, todas as variáveis que foram definidas dentro do escopo de função deixam de existir.

A ciclo de vida de uma variável é definido dentro do escopo de execução da função. O que isto significa é que no console.log (a + b), a variável b existe somente durante a execução da função outer (). Uma vez que a função outer tenha terminado a execução, a variável b não existe mais.

Quando a função é executada pela segunda vez, as variáveis da função são criadas novamente e só são ativadas até a conclusão da execução da função.

Assim, quando outer() é chamado pela segunda vez:

  1. Uma nova variável b é criada, seu escopo é limitado à função outer() e seu valor é definido como 10.
  2. A próxima linha é uma declaração de função, então nada para executar.
  3. return inner retorna todo o corpo da função inner.
  4. O conteúdo retornado pela instrução de return é armazenado em Y.
  5. A função outer() termina a execução e todas as variáveis dentro do escopo de outer() agora não existem mais.

O ponto importante aqui é que quando a função outer() é chamada pela segunda vez, a variável b é criada de novo. Além disso, quando a função outer() termina a execução pela segunda vez, essa nova variável b deixa de existir novamente.

Este é o ponto mais importante a perceber. As variáveis dentro das funções só são criadas quando a função está em execução e deixam de existir quando as funções concluem a execução.

Agora, vamos retornar ao nosso exemplo de código e observar X e Y. Como a função outer() na execução retorna uma função, as variáveis X e Y são funções.

Isso pode ser facilmente verificado adicionando o seguinte ao código JavaScript:

console.log(typeof(X)); //X é do tipo função
console.log(typeof(Y)); //Y é do tipo função

Como as variáveis X e Y são funções, podemos executá-las. Em JavaScript, uma função pode ser executada adicionando () após o nome da função, como X() e Y().

function outer() {
var b = 10;
   function inner() {

         var a = 20; 
         console.log(a+b);
    }
   return inner;
}
var X = outer(); 
var Y = outer(); 
//end of outer() function executions
X(); // X() invocado pela primeira vez
X(); // X() invocado pela segunda vez
X(); // X() invocado pela terceira vez
Y(); // Y() invocado pela primeira vez

Quando executamos X() e Y(), estamos essencialmente executando a função inner.

Vamos examinar passo-a-passo o que acontece quando o X() é executado pela primeira vez:

  1. A variável a é criada e seu valor é definido como 20.
  2. O JavaScript agora tenta executar a + b. Aqui é onde as coisas ficam interessantes. o JavaScript sabe que existe desde que acabou de criá-lo. No entanto, a variável b não existe mais. Como b é parte da função outer(), b só existiria enquanto a função outer() estivesse em execução. Como a função outer() terminou a execução muito antes de chamarmos X(), quaisquer variáveis dentro do escopo da função outer deixam de existir e, portanto, a variável b não existe mais.

Como o JavaScript lida com isso?

Closures

A função inner pode acessar as variáveis da função de inclusão devido ao closures em JavaScript. Em outras palavras, a função inner preserva a cadeia de escopo da função delimitadora no momento em que a função envolvente foi executada e, portanto, pode acessar as variáveis da função delimitadora.

Em nosso exemplo, a função inner preservou o valor de b = 10 quando a função outer() foi executada e continuou a preservá-la (closure).

Agora ele se refere à sua cadeia de escopos e percebe que ele tem o valor da variável b dentro de sua cadeia de escopos, uma vez que ele incluiu o valor de b dentro de um closure no ponto em que a função outer foi executada.

Assim, JavaScript conhece a = 20 e b = 10 e pode calcular a + b.

Nota final

Como vimos no decorrer deste post, saber clousure se torna um item indispensável em nosso canivete suiço chamado JavaScript, portanto estude e transforme este conhecimento em prática tenho certeza que será de grande utilidade no seu dia a dia.

Gostou do conteúdo? não deixe de seguir a uebile nas redes sociais, pois toda semana tem post novo aqui no blog com mais dicas para o seu impulso digital.