Closure (“clausura” em português) é uma função que tem acesso as variáveis do escopo pai, ou seja, do “escopo léxico” que ela está contida (ex: o corpo de uma função, um bloco delimitador). O closure tem três cadeias de escopo: o seu próprio escopo; escopo externo, tendo acesso as variáveis da função exterior; e o escopo que tem acesso as variáveis globais.
Em JavaScript apenas funções possuem um novo contexto léxico.
Um exemplo clássico de um Closure é a criação de um contador sem o uso de uma variável global. Por ex:
Se você tentasse fazer algo do tipo:
| 
					 1 2 3 4 5 6 7 8 9  | 
						function add() {     var counter = 0;     counter += 1;     return counter; } add(); add(); add();  | 
					
Você poderia pensar que o valor de counter no final seria 3. Mas não, ele será sempre 1.
Mas se retornarmos um “função” no lugar de “counter”, teremos assim nossa closure.
| 
					 1 2 3 4 5 6 7 8 9 10  | 
						var add = (function () {     var counter = 0;     return function () {return counter += 1;} })(); // já executa a função anônima aqui        // e retorna para a variável add a função        // function () {return counter += 1;} add(); add(); add();  | 
					
Dessa forma a variável add possui a função function () {return counter += 1;} com acesso ao escopo da função pai (onde foi declarado a variável counter).
Portanto quando chamamos add(),  estamos chamando a função function () {return counter += 1;}, que por sua vez incrementa a variável ‘counter’.
Não muito semelhante, mas equivalente, algo parecido, também possibilita ter funções com variáveis privadas, como no exemplo abaixo:
| 
					 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16  | 
						function MyObject() {     this.public = { a: "aqui é público" }     var private = { a: "aqui é privado" }     this.get_a = function() {         return private.a;     }     this.set_a = function(x) {  // a variável 'private' pode ser alterada apenas através um método         private.a = x;     } } var obj = new MyObject(); console.log(obj.public); // "aqui é público" -> Acessível console.log(obj.private); // undefined -> Inacessível através da instancia console.log(obj.get_a()); // "aqui é privado" obj.set_a("aqui é privado mesmo") console.log(obj.get_a()); // "aqui é privado mesmo"  | 
					
Como demonstrado no exemplo acima, a variável private, “vive” apenas dentro da função e apenas de lá que seu valor pode ser acessado e alterado.
Closure para fazer currying
Currying é uma técnica para transformar uma função que recebe múltiplos parâmetros em uma outra com muito menos parâmetros.
Outra explicação muito boa retirada do insubstituível stackoverflow:
“Currying” é um função que “captura” alguns parâmetros para outras funções e retorna uma função (uma “closure”) que aceita o restante dos parâmetros.
Imagine a função greet:
| 
					 1 2 3 4  | 
						var greet = function(greeting, name) {   console.log(greeting + ", " + name); }; greet("Hello", "Heidi"); //"Hello, Heidi"  | 
					
Com um pequeno ajuste poderíamos fazer uma função para cumprimentar qualquer pessoa sem ter que passar o valor “Hello” para o argumento novamente.
| 
					 1 2 3 4 5 6 7 8 9  | 
						var greetCurried = function(greeting) {   return function(name) {     console.log(greeting + ", " + name);   }; }; var greetHello = greetCurried("Hello"); greetHello("Mateus"); //"Hello, Mateus" greetHello("Padua"); //"Hello, Padua"  | 
					
Valeu, 
 
Abaixo segue as fontes de onde me inspirei para fazer este post:
https://developer.mozilla.org/pt-BR/docs/Web/JavaScript/Guide/Closures
https://www.w3schools.com/js/js_function_closures.asp
https://pt.stackoverflow.com/questions/1859/como-funcionam-closures-em-javascript/1860#1860
https://www.turbosite.com.br/blog/entenda-o-que-sao-closures-em-javascript/
https://www.sitepoint.com/currying-in-functional-javascript/