Closures

6/42
Recursos
Transcripci贸n

Son funciones que regresan una funci贸n o un objeto con funciones que mantienen las variables que fueron declaradas fuera de su scope.

Los closures nos sirven para tener algo parecido a variables privadas, caracter铆stica que no tiene JavaScript por default. Es decir encapsulan variables que no pueden ser modificadas directamente por otros objetos, s贸lo por funciones pertenecientes al mismo.

Aportes 173

Preguntas 16

Ordenar por:

驴Quieres ver m谩s aportes, preguntas y respuestas de la comunidad? Crea una cuenta o inicia sesi贸n.

Apuntes de esta clase:

Unicamente como aporte:

actualmente javascript ha realizado mejoras en la implementaci贸n de la Programaci贸n Orientada a Objetos, mejorando la forma en que se realizan clases, para aplicar variables privadas se puede utilizar el caracter `#``

quedando el ejercicio indicado por el profesor de la siguiente forma:

      class makeCounter {
        #count;

        constructor(n) {
          this.#count = n;
        }

        get count() {
          return this.#count;
        }

        increase() {
          this.#count += 1;
        }

        decrease() {
          this.#count -= 1;
        }
      }

      let counter = new makeCounter(7);

      console.log("The Count is:", counter.count);
      counter.increase();
      console.log("The Count is:", counter.count);
      counter.decrease();
      counter.decrease();
      counter.decrease();
      counter.decrease();
      console.log("The Count is:", counter.count);

      counter.#count = 0;

si intentamos modificar el valor counter nos da la siguiente advertencia:

Es importante mencionar que EcmaScript cada a帽o lanzo nuevos est谩ndares.
Uno de los principales para este a帽o es que contara variables privadas dentro de las clases.

class Message {
  #message = "Howdy"

  greet() { console.log(this.#message) }
}

const greeting = new Message()

greeting.greet() // Howdy
console.log(greeting.#message) // Private name #message is not defined```

Esto es fundamental para aprender React.

Ok esta clase vale su peso en oro, la tuve que repetir como 20 veces, pero me qued贸 claro todo!

Closures

Junto a scope cuando lo combinamos con function podemos crear algo que se llama closure. Para entenderlo veamos un ejemplo:

Agreguemos este archivo a la carpeta de ejercicios:

Closure.html

Tenemos la variable color disponible globalmente. Para evitar que sea global vamos a crear una funci贸n que se va a llamar autom谩ticamente. Esto se logra con IIFE(Immediately-invoked function expressions), es una funci贸n que se llama de la siguiente manera: (function(){})().

(function() {
        let color = "green";

        function printColor() {
          console.log(color);
        }

        printColor();
      })();

Al hacer esto ya la variable color no estar谩 en un 谩mbito global sino funcional. Cuando combinamos un scope con una funci贸n sucede esto que ya hicimos, el famoso clousure. La funci贸n que se encuentra en su interior puede acceder a la variable.

Segundo ejemplo

Vamos a crear una maquina que imprima colores en la consola. Vamos a hacer una funci贸n que nos devuelva otra funci贸n.

function makeColorPrinter(params) {
        let colorMessage = `The color is ${params}`;

        return function() {
          console.log(colorMessage);
        };
      }

      let greenColorPrinter = makeColorPrinter("green");
      console.log(greenColorPrinter());

Ac谩 pasa algo interesante, la funci贸n que est谩 dentro de makeColorPrinter() recuerda el valor de colorMessage a煤n cuando es llamado en la variable greenColorPrinter, est谩 afuera de su scope pero a煤n lo recuerda. A esto se le llama closure, una funcionalidad que el lenguaje no trae por s铆 solo, logramos que se memorizara el scope. El feature que creamos se llama variables privadas.

Variables privadas

Supongamos que tenemos el siguiente c贸digo que crea un contador.

const counter = {
        count: 3
      }

      console.log(counter.count);

No queremos que .log pueda leer nuestra variable, 驴c贸mo la hacemos privada? Para eso tenemos que crear una funci贸n.

    return {
      increase: function() {},
      decrease: function() {},
      getCount: function() {}
    };
  }
  let counter = makeCounter(5)

驴Qu茅 sucede ac谩? Ahora tenemos una variable privada por que si accedemos a counter.count no nos dar谩 ning煤n valor, si usamos console.log(counter.count) no nos arrojar谩 nada, pero s铆 tenemos las tres funciones declaradas disponibles; increase; decrease; getCount. Para acceder al valor de count lo tenemos que hacer usando la funci贸n getCount que s铆 tenemos disponible. Podemos hacer lo siguiente:

getCount:  function()  {
	 return count;
}

Ahora si usamos console.log(counter.getCount()) s铆 nos dar谩 el valor de la variable privada. 隆Sorprendente!

Si no queremos que nuestra variable sea reescrita podemos usar la variable privada usando funciones.

Sigamos implementando

Terminemos de acomodar nuestra funci贸n para agregarles las funcionalidad; decrease; increase.

function makeCounter(n) {
        let count = n;

        return {
          increase: function() {
            count = count + 1;
          },
          decrease: function() {
            count = count - 1;
          },
          getCount: function() {
            return count;
          }
        };
      }
      let counter = makeCounter(5);

Ahora si podemos sumar y restar la variable usando nuestras nuevas funciones:

console.log(counter.getCount()); // 5
      counter.increase()
      counter.increase()
      counter.increase()
console.log(counter.getCount()); // 8
      counter.decrease()
      counter.decrease()
      counter.decrease()
      counter.decrease()
console.log(counter.getCount()); // 4

Pero si queremos cambiar el valor con counter.count = 10 no lo vamos a lograr.

counter.count = 10 // No pasa nada

El valor de la variable privada no se puede acceder directamente ni alterar directamente, se puede lograr mediante algunas funciones.

En resumen鈥 una manera de implementar getters & setters en JavaScript

Hola Comunidad.
.
Este concepto si me ha hecho sufrir, y creo que a todos.
.
Luego de llorar, repetir VARIAS veces este video y buscar informaci贸n complementaria tuve la fortuna de toparme con este video del profesor Sacha en su canal de Youtube.
.
El video aqu铆 馃憠 https://www.youtube.com/watch?v=JXG_gQ0OF74
.
En este video explica muy bien y paso a paso qu茅 es y c贸mo funciona un closure. Lo recomiendo debido a que toc贸 un tema que yo no hab铆a entendido del todo pero que ya me qued贸 m谩s claro: El entorno l茅xico.
.
Este concepto nos permite entender c贸mo es que un closure es capaz de recordar el valor de una variable (m谩s bien el scope superior) que dej贸 de existir al finalizar la funci贸n de la que proviene 馃く.
.
Lo comparto con ustedes para que no pasen horas como yo tratando de entender algo que a decir verdad, no es tan complejo.
.
Espero les sirva.
.
隆Saludos!

Clousure
Te permite que el scope de tu funci贸n sea privada.

Comparto una versi贸n corta de 鈥渕akeCounter鈥:

const makeCouter = (n) => {
                let count = n // private property
                return {
                    increase: () => count = count + 1,
                    decrease: () => count = count - 1,
                    getCount: () => count
                }
            }

Al parecer ya le voy agarrando la onda a esto de los closures. Ya dec铆a yo que no bastaba con retornar funciones.
Al parecer con esta clase, un uso pr谩ctico es el seguir evitando que se contamine el scope global

Javascript: Funciones que son invocadas inmediatamente (IIFE)
https://programacionymas.com/blog/funciones-javascript-invocadas-inmediatamente-IIFE

Una definicion muy sencilla que me gusta mucho es: 鈥淐losure es una funcion que retorna otra funcion, ademas recuerda el scope en el que fueron creadas鈥

La variable privada es accesible 煤nicamente por las funciones retornadas al scope global.

Hola, si eres nuevo en este curso, te recomiendo ver primero la clase 5, luego la 6 y finalmente la 4, as铆 queda todo m谩s claro.

En ES2015 (inicialmente nombrado como ES6) es posible declarar 谩mbitos a nivel de bloque. En ES5 no, y es por ello que se emulaba este comportamiento con el uso de IIFEs.

En pocas palabras, para conseguir un encapsulamiento, antes de ES2015 se hac铆a de esta manera:

(function () { 
    var x = 10;
})();
console.log(x);  // Reference Error: x is not defined

Pero desde la versi贸n ES2015 es posible usar lo siguiente:

{ 
    let x = 10;
};
console.log(x);  // Reference Error: x is not defined

Esta nueva caracter铆stica block scoping es posible usando las palabras reservadas let y const que se introdujeron en el nuevo est谩ndar de Javascript. Sin embargo, var sigue existiendo por cuestiones de compatibilidad.

Por lo tanto, decimos que var tiene alcance a nivel de funci贸n, y no a nivel de bloque. Si queremos encapsular la variable x declarada con var hace falta usar IIFEs, ya que unas llaves no ser谩n suficiente:

{ 
    var x = 10;
};
console.log(x);  // Imprime 10

Pens茅 que los modificadores de acceso eran complicados en Java 馃懡

Excelente clase

Aqu铆 les comparto la documentaci贸n para profundizar
https://developer.mozilla.org/es/docs/Web/JavaScript/Closures

Seg煤n MDN Un closure o clausura es la combinaci贸n de una funci贸n y el 谩mbito l茅xico en el que se declar贸 dicha funci贸n. Es decir los closures o clausuras son funciones que manejan variables independientes. En otras palabras, la funci贸n definida en el closure 鈥渞ecuerda鈥 el 谩mbito en el que se ha creado.

Javascript no acepta variables privadas, por lo que una forma de hacer que las varables s贸lo sean modificadas por si mismas es mediante closures.

Los closures encapsulan variables que no pueden ser modificadas directamente por otros objetos, s贸lo por funciones pertenecientes al mismo, lo que permite asegurar la info.

Para este ejemplo, makeCounter es una funci贸n que regresa un arreglo de funciones mismas que conocen su contexto, osea:

  • son conscientes de las modificaciones de @count, pero nadie m谩s.
<script>
  function makeCounter(n) {
    let count = n;
    return{
      increase : function () {
        count = count+1;
      },
      decrease : function  () {
        count = count+1;
      },
      getCount : function  () {
        return count;
      },
    }   
  }
  let count = makeCounter(7);
  count.increase();
  count.increase();
  count.decrease();
  console.log(count.getCount());
</script>```

Hice el codigo para que se pueda poner el video en full screen al doble click y para pausarlo al darle click al video

function MediaPlayer(config) {
  this.media = config.el
  this.media.onFullScreen = false
  console.log(this.media)
}

MediaPlayer.prototype.play = function () {
  if (this.media.onFullScreen) return //Esto porque cuando esta en full screen
  if (this.media.paused) {
    // El video se pone automaticamente en pausa al clickear sobr el
    this.media.play()
  } else {
    this.media.pause()
  }
}

MediaPlayer.prototype.setFullScreen = function () {
  this.media.requestFullscreen()
  this.media.onFullScreen = !this.media.onFullScreen
}
export default MediaPlayer
import MediaPlayer from './MediaPlayer.js'

const video = document.querySelector('video')
const button = document.querySelector('button')

const player = new MediaPlayer({ el: video })

button.onclick = () => player.play()
video.onclick = () => player.play()
video.ondblclick = () => player.setFullScreen()

Otro Ejemplo rapido:

const sell = product => (currency, price, stock) =>
    console.log(
        `${product} for sell at ${currency}${price}, currently ${stock} in stock.`
    );

const sellAvocado = sell("avocado");
sellAvocado("$", 1, 100);
// -> avocado for sell at $1, currently 100 in stock.

const sellTomatoes = sell("Tomatoes");
sellTomatoes("拢", 1, 1000);
// -> Tomatoes for sell at 拢1, currently 1000 in stock.

En resumen (si estoy mal pueden hacerme la observaci贸n):
Closure es una funci贸n ejecutada (retornada) que se memoriza valores del scope de la funci贸n padre donde se declaro.
Entonces podr铆amos hablar de que se necesitan 3 funciones:
1.- La funci贸n padre.
2.- La funci贸n hija que va retornar los valores que se memorizo del scope function (el contexto de la funci贸n padre).
3.- La funci贸n donde se invoca a la funci贸n padre.
Todo esto basado en el ejemplo, espero puedan dar alg煤n detalle extra.馃

Ejemplo de closure.

let counter = (function () {
  let counterPrivate = 0
  return {
    increment: function () {return counterPrivate += 1},
    decrement: function () {return counterPrivate -= 1},
    value: function () {return counterPrivate},
  };
})();

console.log(counter.increment());
console.log(counter.increment());
console.log(counter.increment());
console.log(counter.decrement());
console.log(counter.value());```

La explicaron de esta clase es estupenda y m谩s cundo lo complementas con el curso de closures y scope
https://platzi.com/clases/scope/
se los recomiendo un mont贸n

confirmen si todos amamos a este profe 馃挭馃徏

Me gusta esto鈥 Mucho, mucho鈥

function makeCounter(n) {
    let count = n;
    return {
      increase: () => count++,
      decrease: () => count--,
      getCount: () => count,
    }
  }

  let counter = makeCounter(7);```

Ac谩 dejo un aporte que puede ayudar a entender mejor las clausuras: https://www.youtube.com/watch?v=JXG_gQ0OF74&ab_channel=LaCocinadelC贸digo, me ayudo un mont贸n a entender este tema.

Espero les sea de ayuda.

Saludos.

Pensaba que sabia JavaScript hasta que llegue a este curso, cada clase se ven cosas muy interesantes, 煤tiles y complejas, en ocasiones me ha tocado ver la misma clase hasta 3 o 4 veces para comprender al 100%

Esto es el encapsulamiento de java con otro nombre, no???

Aqui a los closures les dan un approach para el scope de una funcion y a privacidad de objetos, les recomiendo este video de un muy buen profesor de Platzi donde explica los closures a profundidad
https://www.youtube.com/watch?v=JXG_gQ0OF74&ab_channel=LaCocinadelC贸digo

Una funcion se puede poner dentro de parentesis, si esto pasa crea su propio scope, ahi se pueden definir variables, si luego otra funcion dentro llama a variables dentro de ese scope, es cuando se crea el Closure, tambien se puede hacer un IIFE si se pone otro set de parentesis para que se ejecute inmediatamente

Opino que lo 煤ltimo que hizo el profesor con el counter,d贸nde pretende utilizar variables privadas, se denomina 鈥榤odule pattern鈥 en javascript:

Is used to further emulate the concept of classes in such a way that we鈥檙e able to include both public/private methods and variables inside a single object, thus shielding particular parts from the global scope.

It should be noted that there isn鈥檛 really an explicitly true sense of 鈥減rivacy鈥 inside JavaScript because unlike some traditional languages, it doesn鈥檛 have access modifiers. Variables can鈥檛 technically be declared as being public nor private and so we use function scope to simulate this concept. Within the Module pattern, variables or methods declared are only available inside the module itself thanks to closure. Variables or methods defined within the returning object however are available to everyone.

Obtenido del libro: Javascript design patterns

//Variable privada
        function makeCounter(n){
            let count = n;
            return { //retorna un objeto
                increase: function (m){
                    count+=m;
                },
                decrease: function (o){
                    count-=o;
                },
                getCount: function (){
                    return count;
                },
            }
        }

        let counter = makeCounter(7); //n
        console.log(counter.getCount());

        counter.increase(2);//m
        console.log(counter.getCount());

        counter.decrease(4);//o
        console.log(counter.getCount());

Me pareci贸 genial esta clase, me dejo pensando tantas cosas geniales que se pueden hacer con closures.

buena manera de explicar los temas, excelente

Mis sesos quedaron pegados en el techo, que gran curso Richard y team Platzi

Muy interesantes los closures!

Son geniales los closures

muy bien explicado.

Los closures son la uni贸n entre Scope y las funciones.

Los Closures son una forma de recordar cosas. Si realizamos una funci贸n que necesite recibir algo, pero tambi茅n queremos saber qu茅 fue lo que se pas贸, un closure sirve muy bien. Usualmente el dato que recibe siempre se manipula, pero para evitar que pueda ser le铆do o alterado, se guarda en una varibale dentro de la funci贸n y con m茅todos se ejecutan funciones. Actua como una variable privada.

function makeCounter(n) {
        let count = n;

        return {
          increase: function() {
            count = count + 1;
          },
          decrease: function() {
            count = count - 1;
          },
          getCount: function() {
            return count;
          },
        };
      }

      let counter = makeCounter(7);

      console.log('The count is:', counter.getCount());
      counter.increase(); //8
      console.log('The count is:', counter.getCount());
      counter.decrease(); // 7
      counter.decrease(); // 6
      counter.decrease(); // 5
      counter.decrease(); // 4
      console.log('The count is:', counter.getCount());

      counter.count = 0; // Undefined (no lo puede encontrar)
      console.log('The count is:', counter.getCount());

Entiendo Closure se llama asi por que impide el acceso directo a las variables, como cuando clausuran un lugar y no dejan entrar a nadie.

La parte de variables privadas es algo que no entend铆a como hacerlo en Javascript. Ahora ya tengo un claro ejemplo de como aplicarlo en proyectos

function makeCounter(n) {
	let count = n;

	return {
		increase: function() {
			count = count + 1;
		},
		decrease: function() {
			count = count - 1;
		},
		getCount: function() {
			return count;
		},
	}
}

let counter = makeCounter(7);

console.log('the count is:', counter.getCount();); 

Este es un ejemplo de closures?

function padre(numeroDeHijos) {
	function hijo() {
		let numeroDeHermanos = numeroDeHijos
		console.log('Numero de hermanos ' + numeroDeHermanos)
	}
  hijo()
}

padre(75)

I share my notes!

<!DOCTYPE html>
<html>
  <head>
    <title>Closures</title>
  </head>

  <body>
    <a href="/ejercicios/">Go back</a>
    <p><em>Abre la consola</em></p>

    <script>
      /* Closures Son funciones que regresan una funci贸n o un objeto con funciones que mantienen las variables que fueron declaradas
      fuera de su scope.
      Los closures nos sirven para tener algo parecido a variables privadas, caracter铆stica que no tiene JavaScript por default. Es
      decir encapsulan variables que no pueden ser modificadas directamente por otros objetos, s贸lo por funciones pertenecientes al
      mismo.*/

      //printColor
      //IIFE Una expresi贸n de funci贸n invocada de inmediato es un lenguaje de lenguaje de programaci贸n JavaScript que produce un alcance l茅xico utilizando el alcance de la funci贸n de JavaScript. 
      /*la variable color no estar谩 en un 谩mbito global sino funcional. Cuando combinamos un scope con una funci贸n sucede esto que ya
      hicimos, el famoso clousure. La funci贸n que se encuentra en su interior puede acceder a la variable.*/
            /*
            (function() {
              let color = 'green';

              function printColor() {
                  console.log(color);
              }

              printColor();
            })();
            */
      // Funciones que regresan funciones
      /*Ac谩 pasa algo interesante, la funci贸n que est谩 dentro de makeColorPrinter() recuerda el valor de colorMessage a煤n cuando es llamado en la variable0
      greenColorPrinter, est谩 afuera de su scope pero a煤n lo recuerda. A esto se le llama closure, una funcionalidad que el lenguaje no
      trae por s铆 solo, logramos que se memorizara el scope. El feature que creamos se llama variables privadas.*/
            /*
            function makeColorPrinter(color) {
              let colorMessage = `The color is ${color}`;

              return function() {
                console.log(colorMessage);
              };
            }

            let greenColorPrinter = makeColorPrinter('green');
            console.log(greenColorPrinter());
            */
      //variables "privadas"
      /*驴Qu茅 sucede ac谩? Ahora tenemos una variable privada por que si accedemos a counter.count no nos dar谩 ning煤n valor, si
      usamos console.log(counter.count) no nos arrojar谩 nada, pero s铆 tenemos las tres funciones declaradas disponibles; increase;
      decrease; getCount. Para acceder al valor de count lo tenemos que hacer usando la funci贸n getCount que s铆
      tenemos disponible. Si no queremos que nuestra variable sea reescrita podemos usar la variable privada usando funciones.*/
            /* //Primera Parte
            const counter = {
              count: 3,
            };
            console.log(counter.count);
            counter.count = 99;
            console.log(counter.count);
            */
            //Segunda Parte
            /*
            function makeCounter(n) {
              let count = n;
              return {
                increase: function() {
                  count = count + 1;
                },
                decrease: function() {
                  count = count - 1;
                },
                getCount: function() {
                  return count;
                },
              };
            }

            let counter = makeCounter(7);

            console.log('The count is:', counter.getCount());
            counter.increase();
            console.log('The count is:', counter.getCount());
            counter.decrease();
            counter.decrease();
            counter.decrease();
            counter.decrease();
            console.log('The count is:', counter.getCount());

            counter.count = 0;
            console.log('The count is:', counter.getCount());
            */
    </script>
  </body>
</html>

Para que sea mas rapido, este es el archivo de closures en blanco para que empecemos a trabajar:

closures.html

<html>
  <head>
    <title>Closures</title>
  </head>

  <body>
    <a href="/ejercicios/">Go back</a>
    <p><em>Abre la consola</em></p>

    <script>
      // Closures
      // printColor
      let color = "green";

      function printColor() {
        console.log(color);
      }

      printColor();

      // Funciones que regresan funciones
      // variables "privadas"
    </script>
  </body>
</html>

y esta es la linea que debemos ageregar en ejercicios/index.html:

      <li><a href="/ejercicios/closures.html">closures</a></li>

Excelente, no me canso de aprender cosas nuevas, no sabia lo de las IIFE

Les comparto una lectura sobre patrones de dise帽o, en esta lectura ya tiene 2 de los que el profesor esta utilizando

https://medium.com/@jmz12/patrones-de-dise帽o-en-js-43beab8f5756

        (()=>{
            let makeCounter = number =>{
                let counter = number;
                return {
                    increase: () => counter++,
                    decrease: () => counter--,
                    getCount: () => counter
                }
            }

            let count = makeCounter(9);
            console.info(count.increase(), count.decrease(), count.decrease(),count.decrease(), count.getCount());

        })();

Me surgi贸 una duda, relacionada a la privacidad.
驴Es m谩s correcto crear un web component com propiedades privadas y modificarlas a trav茅s de sus funciones?
He visto componentes de frameworks que tienen las variables p煤blicas, por eso pregunto鈥

Closure en resumidas cuentas es una funci贸n que llama a otra funci贸n y te permite mantener tus variables y datos privados. Que opinan, estoy en el camino correcto?

Es importante poner un punto y coma en la expresi贸n final ante de un nuevo IIFE. Un lugar m谩s para uso obligatorio del punto y coma.

// IIFE
      (function(){
        let color = "green";
        (function(){
          console.log(color)
        })()
      })()
function makeCounter(n) {
  let count = n
  return {
    increase: function() {
      return ++count
    },
    decrease: function() {
      return --count
    },
    getCount: function() {
      return count;
    },
  }
}

let counter = makeCounter(7);

console.log("The count is: ", counter.increase());
console.log("The count is: ", counter.decrease());
console.log("The count is: ", counter.getCount());
// 1 Se guarda y se pone a disposicion (una funcion) getColor.
// 2 Se llama a la misma pasandole por parametro el color blue.
// 3 Se almacena el valor en inputColor y se retorna una funcion,
// esta almacena en su scope, el valor de inputColor.
// 4 Disparamos get - que es una funcion (una clousure) que recuerda su ambito.
// 5 Vemos en la consola en valor de inputColor.

// 1- 
    let getColor = (color) => {
    let inputColor = color; 
    // 3
    return function(){
        // 5
        console.log(inputColor);
    }  
}
// 2-
let get = getColor("blue");
// 4
let paint = get();

Excelente clases !
Dejo un articulo sobre las funciones IIFE: https://developer.mozilla.org/es/docs/Glossary/IIFE

Apuntes de la clase鈥

/*
Closures, una de las tecnicas mas usadas
printColor
*/

/* IIFE Funcion autoejecutable
  printColor dentro de un iife
*/
(function(){
  let color = 'green';

  function printColor(){
    console.log(color);
  }

  printColor();
})()

// Funciones que retornan funciones

function makeColorPrinter(color){
  let colorMessage = `El color es ${color}`;
  return function(){
    console.log(colorMessage);
  }
}

/* greenColorPrinter "recuerda" el valor de la funcion
  que lo contiene, en este caso makeColorPrinter
*/
let greenColorPrinter = makeColorPrinter('green');
console.log(greenColorPrinter());


// Variables "privadas"

// const counter = {
//   count: 3
// }

function makeCounter(n){
  /* Variable privada, no se puede modificar
    ni leer desde ningun otro lado
  */
  let count = n;

  return {
    increase: function(){
      count++;
    },
    decrease: function(){
      count--;
    },
    getCount: function(){
      return count;
    }
  }
}

let counter = makeCounter(7);
console.log(`El contador es: ${counter.getCount()}`);
counter.increase();
console.log(`El contador es: ${counter.getCount()}`);
counter.decrease();
counter.decrease();
counter.decrease();
counter.decrease();
console.log(`El contador es: ${counter.getCount()}`);```

Excelente. Se entiende muy bien

Closures

  • Es la combinaci贸n del scope de una funci贸n y la funci贸n declarada dentro de ese scope.
  • La funci贸n externa retorna la funci贸n interna (u objeto con funciones).
  • La funci贸n interna accede a las variables definidas en la funci贸n externa, es decir, mantiene variables declaradas fuera de su scope.
  • El 谩mbito lexical permite este comportamiento.

脕mbito lexical

  • El alcance o 谩mbito l茅xico permite buscar a la variable desde el alcance de ejecuci贸n hacia el alcance externo de la funci贸n hasta encontrarla.
  • Dicha b煤squeda lo realiza el int茅rprete de JS.
  • Si la variable no se encuentra en ning煤n 谩mbito se genera una excepci贸n.
  • No importa de donde o como se llame la funci贸n, su alcance l茅xico depende solo de donde se declar贸 la funci贸n.

Funci贸n IIFE(Immediately-invoked function expressions)

  • Es una funci贸n que se llama autom谩ticamente.
  • Se escribe de la siguiente manera: (function(){})().

Variables privadas

  • El valor de la variable privada no se puede acceder directamente ni alterar directamente, se puede mediante algunas funciones.
  • Los closures nos sirven para tener algo parecido a variables privadas, caracter铆stica que no tiene JavaScript por default.

ME ENCANTA LA DEFINIC脥ON QUE TIRA RICHARD AL FINAL DE LA CLASE:
DEFINICION de CLOSURE
Es una t茅cnica para establecer variables privadas consiguiendo as铆 una caracter铆stica que el lenguaje de por s铆, no tiene.
Pudiendo manejar estos valores a trav茅s de m茅todos predefinidos y evitar efectos no deseados.

hasta donde pude probar estos conceptos en react veo que siempre tenemos variables privadas y que esta librer铆a a partir de warnings x consola te lleva a trabajar por componentes en 谩mbitos l茅xicos algo m谩s declarativos.

Para repasar mas profundamente el tema de esa clase les dejo el link a mis apuntes del curso del gran Oscar Barajas "Scopes y Closures"
scopes&closures
https://docs.google.com/presentation/d/15fhkS0Wej4Oo6wZxg3i2x68jsZiALMP2_PZWRP_TQYw/edit?usp=sharing

Podemos concluir que los closures, son el uso de funciones para encapsular variables o dataos que no queremos que sean accesibles de forma global.

Definicion de Closures

Una clausura o closure es una funci贸n que guarda referencias del estado adyacente (谩mbito l茅xico). En otras palabras, una clausura permite acceder al 谩mbito de una funci贸n exterior desde una funci贸n interior. En JavaScript, las clausuras se crean cada vez que una funci贸n es creada.

referencia

Hola chicos馃憢! Para que quede mas claro el concepto:
.
Un closure se crea al momento de correr una funci贸n, y puedes acceder a las variables que se encuentran declaradas en el scope superior (afuera de la funci贸n).馃榾

Closure es una forma efectiva de evitar Entidades anemicas.

Muy buena clase, me quedo m谩s claro que es un closure y lo m谩s importante, menciona forma de como se pueden implementar .
Pero lo de las variables privadas estuvo espectacular.

Excelente explicaci贸n la del profesor

que porfesor tan malo , habla todo rapido y como con la lengua pegada, no se sabe dar a entender

驴Qu茅 es un closure? fn que retorna otra fn que puede acceder a las variables de la primera

puedes usar 鈥渃lases鈥 tambien como alternativa y usar hash para tener variables privadas 馃槂 https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Classes/Private_class_fields

En pocas palabas, los closures son clases, o prototipos, como quieras verlo.

Solo que vienen declarados de una manera distinta鈥

Porque si nos ponemos a ver, los clousures son funciones dentro de funciones.

Del mismo modo que son los prototipos.

Esto seria como el esqueleto del prototipo.

IIFE

Entre las nuevas cosas de ES11 si mal no estoy hay algo como esto, pero solo sobre 鈥渃lass鈥, se llaman private fields

IIFE: Expresi贸n de funci贸n ejecutada inmediatamente

Las expresiones de funci贸n ejecutadas inmediatamente (IIFE)聽son聽funciones que se ejecutan tan pronto como se definen.

(function () {
    statements
})();

Es un patr贸n de dise帽o tambi茅n conocido c贸mo聽funci贸n autoejecutable y se compone por dos partes. La primera es la funci贸n an贸nima con alcance l茅xico encerrado por el聽聽Operador de Agrupaci贸n(). Esto impide accesar variables fuera del IIFE, as铆 c贸mo contaminar el alcance (scope) global.
Fuente: https://developer.mozilla.org/es/docs/Glossary/IIFE

Siento que me he perdido en las clases, porque desde el principio no s茅 si debo clonar el repositorio o empezar los archivos desde el principio, porque siempre empieza la clase con archivos ya escritos, y cuando los voy a descargar est谩 toda la clase y no puedo ir escribiendo el c贸digo a la par del profesor

Uy, me encanto la opci贸n de devolver un objeto, se va mucho mas ordenadito el c贸digo

Podr铆a decirse que Scope es como un 鈥encapsulamiento

A los que quieran profundizar un poco, les recomiendo leer:
https://developer.mozilla.org/es/docs/Web/JavaScript/Closures

En el caso de la variable privada, nosotros no podemos acceder a counter.count porque no hay ning煤n valor en el objeto que se llame count, por lo tanto, no podr铆amos nunca acceder a ese valor.
.
A los 煤nicos valores a los que podr铆amos acceder es a: 鈥渋ncrease, decrease y getCount鈥

Da instrucciones que no hicimos de inicio!! Tengan cuidado de seguirle el ritmo.

La funci贸n que hizo el profe que retorna un objeto con 鈥渇unciones鈥 se puede hacer gracias ES6 de la siguiente manera. que en vez de retornar un objeto con funciones, retorne un objeto con m茅todos propiamente, como existen en otros lenguajes de programaci贸n orientados a objetos basados en clases.

function makeCounter(n) {
        let count = n;

        return {
          increase: function() {
            count = count + 1;
          },
          decrease: function() {
            count = count - 1;
          },
          getCount: function() {
            return count;
          },
        };
      }
function makeCounter(n) {
        let count = n;

        return {
          increase() {
            count = count + 1;
          },
          decrease() {
            count = count - 1;
          },
          getCount() {
            return count;
          }
        };
      }

6. Closures

Una clausura o closure es una funci贸n que guarda referencias del estado adyacente (谩mbito l茅xico). En otras palabras, una clausura permite acceder al 谩mbito de una funci贸n exterior desde una funci贸n interior. En JavaScript, las clausuras se crean cada vez que una funci贸n es creada.

脕mbito l茅xico


function iniciar() {
  var nombre = "Mozilla";  // La variable nombre es una variable local creada por iniciar.
  function mostrarNombre() {  // La funci贸n mostrarNombre es una funci贸n interna, una clausura.
    console.log(nombre);  // Usa una variable declarada en la funci贸n externa.
  }
  mostrarNombre();
}
iniciar(); 

Otro Ejemplo

Clousores y IIFE (Expresi贸n de funci贸n ejecutada inmediatamente)

En este caso se tiene una IIFE (Immediately Invoked Function Expression) Las expresiones de funci贸n ejecutadas inmediatamente son funciones que se ejecutan tan pronto como se definen. Estas funciones van encerradas entre par茅ntesis para indicar su ejecuci贸n de inmediato y pueden o no llevar nombre.

Se puede apreciar que dentro del scope de la funci贸n IIFE, existe una variable y una funci贸n y dicha funci贸n puede recordad el valor de variable y esto se debe a que est谩n en el mismo scope.

(function() {
	let color = 'green';
	
	function printColor() {
	    console.log(color);
	}
  printColor();
})();

Clousores y funciones que retornan funciones

Los clousores permiten que Funciones retornen funciones

function makeColorPrinter(color) {
	let colorMessage = `The color is ${color}`;

	return function () {
		console.log(colorMessage);
	};
}

let greenColorPrinter = makeColorPrinter('green');
console.log(greenColorPrinter()); //<- Esto ejecutar谩 la funci贸n retornada
// console.log(greenColorPrinter) //<- esto retonar谩 una funci贸n

Clousores y variables privadas

En ocasiones se tiene variables dentro de un contexto, y como programadores se desea que no se modifiquen desde cualquier parte del c贸digo, pero que si permita realizar operaciones sobre esa variable sin que cambie su valor.

La soluci贸n es crear una funci贸n que aloje la variable con su valor inicial, y que retorne funciones que permitan operar sobre esta variable.

  • Ejemplo 1, se puede observar como se puede modificar una variable desde cualquier parte del c贸digo.
  • Ejemplo 2, se puede observar como se puede encapsular una variable haci茅ndola privada al entorno global.

Ejemplo 1

const counter_1 = {
	count: 3,
};
console.group('Ejemplo 1');
console.log(counter_1.count); // muestra 3, se muestra la variable original
counter_1.count = 99; // se cambia la variable externamente
console.log(counter_1.count); //99
console.end();

Ejemplo 2

// Ejemplo 2

function makeCounterPrivade(n) {
	let countPrivate = n;

	return {
		increase: function () {
			countPrivate = countPrivate + 1;
		},
		decrease: function () {
			countPrivate = countPrivate - 1;
		},
		getCountPrivate: function () {
			return countPrivate;
		},
	};
}
let counter_2 = makeCounterPrivade(7); //

console.group('Ejemplo 2');
console.log('The count is:', counter_2.getCount());
counter_2.increase();
console.log('The count is:', counter_2.getCount());
counter_2.decrease();
console.log('The count is:', counter_2.getCount());

// se declara un nuevo valor y conserva el valor inicial
counter_2.count = 0;
console.log('The count is:', counter_2.getCount());
console.groupEnd();
////////////////////////////////

Simplemente hermoso como lo explica Richard

Si quieren saber m谩s acerca de las clausuras o closures les recomiendo este video de Sasha (el profe de fundamentos de JS 2018)
https://www.youtube.com/watch?v=JXG_gQ0OF74&t=3s

Para entender m谩s f谩cil el tema de los closures es necesario recordar los 3 tipos de funciones que existen:

//Funciones Declarativas
function x( par谩metros ) { l贸gica + return }

//Funciones Expresivas
const y = function( par谩metros) { l贸gica + return }

//Funciones Flecha (Arrow Functions)
const z = ( par谩metros ) => { l贸gica + return }

Si decimos que un closure es una funci贸n que devuelve otra funci贸n entonces:

function x( color ) {
	let texto = `Esto es un color ${ color }`
	return function() {
		console.log( texto )
	}
}
let y = x( 'verde' )
y()

Al llamar a la funci贸n x y pasarle como par谩metro el color 鈥榲erde鈥 estoy guardando dentro de la variable y lo siguiente:

let y =  function() {
		console.log( `Esto es un color verde` )
	}

Convirtiendo de este modo a y en una funci贸n del tipo expresiva y ya no estamos hablando de una variable. Por tanto para llamar a esa funci贸n se hace coloc谩ndole () y retornar谩 el console.log(). Por eso es que se dice que recuerda el valor de la variable de la funci贸n x. Pues claro esto no es magia, si guardas algo en una variable ah铆 se queda en memoria. Lo de las variables privadas es un truco porque es un hecho que no se puede acceder desde el entorno de ejecuci贸n global al entorno de ejecuci贸n de una funci贸n. Entonces lo que estamos haciendo con el closure es obteniendo diferentes resultados a partir de un par谩metro inicial que le pas茅 a la funci贸n principal, cuyo par谩metro lo estoy relacionando directamente a la variable que declaro en la funci贸n x.

function x ( c ) {
    let numero = c
    return function() {
        numero = numero + 1
        return numero
        }
}
let contar = x( 8 )
console.log( contar() )

Es lo mismo que esto:

function x ( c ) {
    let numero = c
    return () => {
        numero ++
        return numero 
	}
}
let contar = x( 8 )
console.log( contar() )

De esta manera es solo podemos modificar el valor de numero con las funciones que devuelve la funci贸n x. El profesor usa un objeto de funciones para tener una mayor variedad de formas para cambiar el valor de dicha variable. En resumen se comporta como una variable que uno define como se quiere modificar y cuando, lo que la hace privada(nosotros tenemos el control)

Si quieren entender ,deben leer a juro los comentarios de los compa帽eros鈥 la explicacion tiene muchas deficiencias.

Closures
Si juntamos el scope con funciones podemos crear algo llamado Closure. Un closure es una funci贸n que recuerda el valor de una variable que no est谩 en su dominio.

Con los closures podemos simular variables privadas, getter y setters en JavaScript.

Lo que se hace es declarar una funci贸n que recibe el valor inicial de count, despu茅s esta funci贸n regresa un objeto con los m茅todos para manipular el valor de count. De esta forma, el objeto creado a partir de la funci贸n makeCounter no contiene el valor de count, sino los m茅todos que regresa, as铆 el valor de counte no puede ser consultado o modificado m谩s que por los m茅todos.

IIFE

Inmediatly Invoked Function Expression. Es una funci贸n que se ejecuta inmediatamente despu茅s de que se declara.

Variables privadas es lo mismo que la encapsulaci贸n en los lenguajes orientados a objetos basados en clases.

    // Other example
    console.log('---- Other example ----');

    const userAldo = {
      firstName: 'Aldo Cesar',
      lastName: 'Fabro',
      year: 32,
      profession: 'Developer',
    }

    function createCopyUser(user) {
      let userCopy = Object.assign({}, user);
      console.log('same', user === userCopy); // false

      return {
        getUser: () => userCopy,
        getFirstName: () => userCopy.firstName,
        getLastName: () => userCopy.lastName,
        getProfession: () => userCopy.profession,
        getYear: () => userCopy.year,
        getFullName: () => `${userCopy.firstName} ${userCopy.lastName}`,
        setProfession: (profession) => userCopy.profession = profession,

      }
    }
    const aldo = createCopyUser(userAldo);

    console.log('user', aldo.getUser());
    aldo.setProfession('Full Stack development');
    console.log('user', aldo.getUser());
    console.log('originalUser', userAldo);
    console.log('Hello', aldo.getFullName());

pense que las variables privadas eran mas simples pero se ve que hay cosas que estan mejorando.

Muy recomendado usar closures. Especialmente para los que arrancan, incorporen bien esto porque lo van a usar mucho en entornos profesionales de trabajo

Los closures son la uni贸n entre Scope y las funciones.

Si entiendo closure es cuando una funci贸n puede acceder a las variables de una funci贸n padre (Wrapper? o algo asi)

conclusiones

tercer ejemplo

otro ejemplo de closures