Cierre en JavaScript

Mar 18 2023
¿Qué es Closure y cuándo podemos usarlo realmente? Para comprender Closure, necesitamos conocer 2 conceptos simples en JavaScript: funciones anidadas y devolución de una función. Funciones anidadas En JavaScript, podemos tener funciones anidadas.

¿Qué es Closure y cuándo podemos usarlo realmente?

Para comprender Closure, necesitamos conocer 2 conceptos simples en JavaScript: funciones anidadas y devolución de una función.

Funciones anidadas

En JavaScript, podemos tener funciones anidadas. La función interna tiene acceso a las variables y parámetros de la función externa.

Veamos el siguiente ejemplo:

function greetPerson(name) {
  const message = 'Hello';
  
  function displayMessage() {
    console.log(`${message} ${name}!`);
  }

  displayMessage();
}

greetPerson('Alex'); // Hello Alex!

Devolver una función

Además de declarar e invocar una función interna dentro de la función externa, también podemos devolver la función interna para que pueda ser invocada desde el exterior.

Veamos un ejemplo de esto:

function greetPerson(name) {
  const message = 'Hello';
  
  function displayMessage() {
    console.log(`${message} ${name}!`);
  }

  return displayMessage;
}

const displayMessageFunction = greetPerson('Alex');

console.log(typeof(displayMessageFunction)); // function
displayMessageFunction(); // Hello Alex!

Cierre

Después de entender estos 2 conceptos, la "definición" de cierre es bastante simple.

El cierre significa que una función interna tiene acceso a las variables y los parámetros de su función externa incluso después de que la función externa haya regresado.

Veamos otro ejemplo donde podemos ver exactamente cómo se puede usar el cierre:

function counterFunction() {
 let counter = 0;

 function increaseCounter() {
  return counter += 1;
 }

 return increaseCounter;
}

// counter reffers to the increaseCounter returned by the counterFunction
const counter = counterFunction();

console.log(counter()); // 1
console.log(counter()); // 2
console.log(counter()); // 3
console.log(counter()); // 4

Una función interna no guarda una copia separada de una variable externa, sino que hace referencia a la variable externa. En otras palabras, el valor de countercambiará si lo cambia usando la función interna.

La función externa counterFunctiontambién devuelve una referencia a la increaseCounterfunción interna, por lo que cuando la llamemos, el valor real de la countervariable cambiará. De esta forma, podemos ver que la countervariable tiene un nuevo valor incrementado después de cada counter()llamada.

¿Cuándo usar Closure?

Podemos usar el cierre para lograr la encapsulación en JavaScript. Esto se puede lograr ocultando la implementación detallada. De esta forma, podemos crear variables y funciones privadas.

Veamos el siguiente ejemplo, donde queremos encapsular algunos datos usando solo funciones y objetos:

const counter = (function () {
  let privateCounter = 0;

  function changeBy(val) {
    privateCounter += val;
  }

  function increaseCounter() {
    changeBy(1);
  }

  function decreaseCounter() {
    changeBy(-1);
  }

  function decreaseCounter() {
    return privateCounter;
  }

  return { increaseCounter, decreaseCounter, getCounterValue };
})();

console.log(counter.getCounterValue()); // 0

counter.increaseCounter();
counter.increaseCounter();

console.log(counter.getCounterValue()); // 2

counter.decreaseCounter();

console.log(counter.getCounterValue()); // 1

Podemos controlar el valor del contador desde afuera, solo llamando increaseCountera y decreaseCounter, y podemos obtener el valor llamando a la getCounterValuefunción, que se comporta como un getter.

De esta manera, podemos simular los publicespecificadores privatede acceso y lograr la encapsulación.

Este es un concepto muy poderoso en el desarrollo de software, ya que evita modificaciones no deseadas de variables y funciones que deberían permanecer privadas.

¡Eso es todo!

Gracias por tomarse el tiempo de leer este artículo sobre Closure en JavaScript. ¡Espero haberte ayudado a comprender mejor este importante concepto y cómo se puede usar para lograr la encapsulación y crear variables y funciones privadas!