Aún no tienes acceso a esta clase

Crea una cuenta y continúa viendo este curso

Cómo crear variables privadas con closures

8/12
Recursos

Aportes 96

Preguntas 22

Ordenar por:

¿Quieres ver más aportes, preguntas y respuestas de la comunidad? Crea una cuenta o inicia sesión.

Variables privadas con Closures: JS por su naturaleza no fomenta el uso de datos privados pero por medio de los Closures podemos crear valores que solo puedan ser accedidos por medio de métodos, que no van a estar disponibles fuera de esta función.

Les dejo el mismo ejemplo pero usando getter y setter

const person = () => {
  let name = 'Name'

  return {
    get name () {
      return name
    },

    set name (value) {
      name = value
    }
  }
}

const newPerson = person()
console.log(newPerson.name)
newPerson.name = 'Jousmo'
console.log(newPerson.name)

Cuando inicializa newPerson no usa var, let ni const porque JS permite no usar el syntax var si se inicializa directamente una variable. Es decir lo que hizo sería el equivalente a:
var newPerson = person();
Dicho esto, declaren variables con:
1.) const (excepto cuando la variable deba ser reasignada, const no lo permite)
2.) let (resto de las veces)

3.) var (NUNCA)

Ésto es muy similar a POO, cuando se instancia el closure se ejecuta el constructor y se regresan los métodos públicos. De ésta forma podemos tener métodos y variables privadas.

Para los que llegaron hasta aquí pero no comprenden aún el tema, les dejo el mismo ejemplo un poco modificado y con comentarios:

const person = () => {
    let nombre = "sin nombre"; // Se declara la variable con let justo en la raíz de la función para que pueda ser vista en todos los niveles interiores.
    return { // Se retorna un "objeto" con 2 "metodos" (funciones)
        obtenerNombre: () => { // método 1, que no recibe parámetros y sólo devuelve la variable nombre.
            return nombre;
        },
        definirNombre: (nuevoNombre) => { // método 2, que recibe un parámetro y lo asigna a la propiedad nombre definida en la raíz de este objeto.
            nombre = nuevoNombre;
        }
    };
};
const mipersona = person(); // Define la constante mipersona y le asigna el objeto (la función) persona, recibiendo asi los 2 métodos (obtenerNombre y definirNombre).
console.log(mipersona.obtenerNombre()); // Te dará el valor por omisión que en este caso sería sin nombre.
mipersona.definirNombre('Jonny'); // Asignas un nuevo nombre por medio del método definirNombre().
console.log(mipersona.obtenerNombre()); // Te dará el nuevo valor que asignaste la línea anterior.

Ahora la explicación es esta. mipersona se declara como constante porque realmente la “constante” mipersona no será modificada en lo absoluto, sino que por medio de su método “definirNombre()” se modifica sólamente una de sus propiedades, que en este caso sería “nombre”, ya que esta propiedad “nombre” no puede ser accesible de ninguna forma fuera del objeto (la función) “persona” mas que por medio de propios métodos (scope de función).

Para los que apenas comienzan con JavaScript, es importantísimo que entiendan este concepto de los closures pues son los principios de la programación orientada a objetos que se ven más adelante.

Espero despejar algunas dudas. Happy Coding!

Ejemplo de un Monedero

const person = () => {
  let saveName = "Name";
  return {
    getName: () => saveName,
    setName: (name) => {
      saveName = name;
    },
  };
};

const newPerson = person();
console.log(newPerson.getName());
newPerson.setName('Edward');
console.log(newPerson.getName());```

Cómo crear variables privadas con closures



JavaScript por su naturaleza no fomenta el uso de datos privados. Pero por medio de los closures podemos crear valores que pueden ser solo accedidos por medio de métodos y que no estarán disponibles fuera de la función.

Primeramente traemos getName, o sea que vamos a traer su valor asignado. En esta caso Name .

Después le estoy asignando otro valor con setName y posteriormente volviendo a imprimir. Pero nosotros no podemos reasignar ni cambiar el valor de saveName desde el otro lado de la app, tendría que disponer de los métodos que acabamos de crear.

const person = () => {
  var saveName = "Name";
  return {
    getName: () => {
      return saveName;
    },
    setName: (name) => {
      saveName = name;
    },
  };
};

newPerson = person();
console.log(newPerson.getName());
newPerson.setName('Oscar');
console.log(newPerson.getName());

De esta forma estamos generando un valor/propiedad que es privado y que no tenemos acceso a ella y de igual manera podemos usar los closures para crear datos privados.

Otro ejemplo:

var makeCounter = function() {
  var privateCounter = 0;
  function changeBy(val) {
    privateCounter += val;
  }
  return {
    increment: function() {
      changeBy(1);
    },
    decrement: function() {
      changeBy(-1);
    },
    value: function() {
      return privateCounter;
    }
  }  
};

var Counter1 = makeCounter();
var Counter2 = makeCounter();
alert(Counter1.value()); /* Muestra 0 */
Counter1.increment();
Counter1.increment();
alert(Counter1.value()); /* Muestra 2 */
Counter1.decrement();
alert(Counter1.value()); /* Muestra 1 */
alert(Counter2.value()); /* Muestra 0 */ 

Camel case

Lo prácticamente lo que genera Oscar es un patron de diseño de JS el cual se le conoce como el patron modulo,

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

no se supone que la variable saveName es privada entonces porque cuando le cambio el nombre desde afuera me lo cambia sin problemas ?


const person = ()=>{
    var saveName = "Name";
    return{
        getName: ()=>{
            return saveName;
        },
        setName: (name)=>{
            saveName = name;
        }
    };
};




newPerson = person();
console.log(newPerson.getName());
newPerson.setName("Jaime");
console.log(newPerson.getName());

saveName ="otherName";
console.log(saveName);


esto tiene parecido con el patrón module, cool 😃

Esto me costo mucho dure un buen rato practicando pero por fin puedo hacerlo solo y entenderlo

const person = () => {
  var saveName = 'Name';
  return {
    getname: () => {
      return saveName;
    },
    setName: name => {
      saveName = name;
    },
  }
}

newPerson = person()

newPerson.setName('Oscar')
console.log(newPerson.getname());

Para qué sirve tener variables privadas?

Esto también se explica en el curso profesional de JavaScript, y está increíble, cuando lo aprendí fue como “whaaaaaaaat” al fin supe cómo usar variables provadas jajaja, y luego vimos TypeScript xD

Este ejemplo esta basado en el patro modulo.

El patrón Módulo encapsula “privacidad”, estado y organización mediante closures.
El patrón de módulo se usa para emular el concepto de clases de tal manera que podamos incluir tanto métodos públicos / privados como variables dentro de un solo objeto, asi todo lo que esta afuera puede acceder a los closures privados.

<function tesModule () {
    var counter = 0;

    return {
        incrementCounter: function () {
            console.log('increment counter');
            return counter++
        },

        resetCounter: function () {
            console.log("value previus to reset: " + counter)
            reset = 0;
        }
    }
}

let module1 = tesModule();
module1.incrementCounter();
module1.incrementCounter();
module1.incrementCounter();
module1.resetCounter();>

//output
increment counter
increment counter
increment counter
value previus to reset: 3

Y cuando creía que ya había visto lo suficiente, aparece el return con métodos adentro 🤯
JavaScript no deja de sorprenderme.

Cuando le vas agarrando el tiro a esto y llega una variable privada 😕

Me costo un poco entender como funciono este codigo, sin embargo es cuestión de ver el codigo un poco menos a lo tradicional, lo unico que hay es una función dentro de return que me cambia el valor de saveName y otra que me lo muestra sin acceder directamente a la variable saveName y entiendo que por eso se llama variable privada

asi quedo mi codigo, cambie el nombre de las variables para ensayar

const person = () => {
    var saveName = 'Name';
    return {
        salirNombre:() => {
            return saveName;
        },
        cambiarNombre: (name) => {
            saveName =name;
        }
    }
};

newPerson = person();
console.log(newPerson.salirNombre());
newPerson.cambiarNombre('luis');
console.log(newPerson.salirNombre());

Saludos companeros tengo una duda pporqeu cuando hace la instancia de la cunfion no la guarda con let o const o var?:

Respuesta a:
Cómo crear variables privadas con closures
const person = () => {
    var saveName = "Pedro";
    return {
        getName: () => {
            return saveName;
        }, 
        setName: (name) => {
            saveName = name;
        },
    };
};

newPerson = person(); // A esta linea me refiero

Es interesante esto de las variables privadas. Recien lo acabo de aprender en la universidad con POO y en el curso de Platzi de POO tambien lo mencionan

Bendito sea el POO en Java que me dejó entender rápido este tema, a diferencia del tema anterior. Je

Alguien podria explicarme la sintaxis que usa dentro del bloque de codigo return y por que usa ‘:’ en vez de ‘=’

    return {
        getName: () => {
            return saveName
        },
        setName: (name) => {
            saveName = name
        }
    }

muchas gracias

Closures

Variable privadas : Mediante closures podemos crear variables que sean accedidas sólo mediante métodos definidos y no puedan ser accedidos directamente fuera de la función en que fueron definidos y así funcionen de manera privada ya que nativamente javascript no fomenta el uso de este tipo de datos privados.

// Private methods

const person = () => {
  var saveName = "Name";

  return {
    getName: () => {
      return saveName;
    },
    setName: (name) => {
      saveName = name;
    },
  };
};

newPerson = person();
console.log(newPerson.getName());

newPerson.setName("Patricio");
console.log(newPerson.getName());

Repositorio 🐙

const person = () => {
  var saveName = "Name";
  var saveEdad = Number(16);
  return {
    getName: () => {
      console.log(`Hola ${saveName} tienes ${saveEdad}`);
    },
    setName: (name, edad) => {
      saveName = name;
      saveEdad = edad;
    },
  };
};

nuevaPersona = person();
nuevaPersona.setName("pepe", 50);
nuevaPersona.getName();

nuevaEstudiante = person();
nuevaEstudiante.setName("Mari", 18);
nuevaEstudiante.getName();

Por medio de closures se pueden crear variables privadas. Es decir, se pueden acceder a estas variables sólo si se usan métodos. Si intentamos hacer un

console.log(saveName);

obtendremos un error diciendo que la variable no está definida.

const person = () => {              //funcion para crear un objeto de tipo persona
    var saveName = "Name";          //creamos la variable donde se almacena el valor
    return {                        //la función nos devuelve dos funciones, una para
        getName: ()=>{              //obtener el valor de la variable
            return saveName;
        },

        setName: (name)=> {         //otra función para establecerlo
            saveName = name;
        }
    }
}

newPerson = person();               //creamos el objeto y obtenemos el valor con el método get
console.log(newPerson.getName());

newPerson.setName("Samuel")         //en el objeto creado establecemos un nuevo valor para saveName
console.log(newPerson.getName())```
<
const perro = ( nombre, raza ) => {
    let _nombre = nombre;
    let _raza = raza;

    return {
        obtNombre: () => _nombre,
        obtRaza: () => _raza,
        asignarNombre: ( nuevoNombre) => _nombre = nuevoNombre,
        asignarRaza: ( nuevaRaza ) => _raza = nuevaRaza
    }
}

const firulais = perro( 'Firulais', 'Sabueso');
const poppy = perro( 'Poppy', 'Labrador');

console.log(firulais._nombre);//undefined
console.log(firulais.obtNombre());//firulais
console.log(firulais._raza);//undefined
console.log(firulais.obtRaza());//Sabueso
console.log(poppy.obtNombre());//Poppy
console.log(poppy.obtRaza());//Labrador>

hmm si tenemos estados globales y solo mediante funciones cambias estos se determinaria como un closure ?


Es bastante similar al concepto de la POO para solo con getters y setters manipular los datos lo cual hace mas seguro cada cambio sin ponerse crudamente al crearse.

__

De igual manera es similar el uso al respecto de funciones dentro del return para cambiar los datos y leerlo, esto no es la misma manera de hacerlo directamente dentro del scope para la persona ?

Tambien esta a una forma para gregar las funciones y se vean mejores ademas que se parecen al exportar modulos de nodejs 💚:

const person = () => {
    // Convertir a una variable "privada"
    // hacer que solo mediante la funcion se pueda cambiar el estado y no desde afuera sin funciones osea practicamente directamente cambiarle su valor
    let guardarNombre = "Name";
    // asegurar los cambios de la variable privada la cual soo se puede modificar por metodos y jamas por valor directo
    const estadoNombre = () => {
        return guardarNombre;
    };
    // Creacion de un pseudo-objeto para manipular estados
    return {
        getName: () => {
            return guardarNombre;
        },
        setName: (nombre) => {
            guardarNombre = nombre;
        },
        estadoNombre
    };
};

nuevaPersona = person();
console.log(nuevaPersona.getName());
nuevaPersona.setName('Rene');
console.log(nuevaPersona.getName());
console.log(nuevaPersona.estadoNombre());

Material de apoyo para reforzar el conocimiento dictado por el profesor -> https://lazamar.github.io/closures-private-variables-and-methods-in-javascript/

Si, es un poco enredado.

const nombre = 'NameLess';
const person = () => {
    var saveName = nombre;
    return {
        getName: () => {
            return saveName;
        },
        setName: (name) => {
            saveName = name;
        },
    };
};

newPerson = person();
console.log(newPerson.getName());
newPerson.setName('Fran');
console.log(newPerson.getName());

PRIMERA VEZ QUE VEO ESA MANERA DE ESCRIBIR FUNCIONES!!! (lo digo por setName y getName).
Ni siquiera en el curso de Sacha Lifszyc que lamentablemente sacaron xq estaba buenísimo.
Va mi aporte!

const person = () => {
  let saveName = "sin nombre";

  return {
    getName: () => {
      return saveName;
    },
    setName: (newName) => {
      saveName = newName;
    },
  };
};

const myPerson = person();
console.log(myPerson.getName());
myPerson.setName("Jonny");
console.log(myPerson.getName());

wow sorprendente. Claro si no quieres usar TypeScript.
mas sin envargo WOOOOOOOOOOOW

ni p idea …

Supongo que las clases resuelven todo este dilema…

const person = () => {
    let saveName = 'Name';

    return {
        getName: () => {
            return saveName;
        },
        setName: (name) => {
            saveName = name;
        }
    }
}

const newPerson = person();

console.log(newPerson.getName());

newPerson.setName('Eduardo');

console.log(newPerson.getName());
console.log(newPerson.saveName);

newPerson.saveName = 'TEST'

console.log(newPerson);
console.log(newPerson.getName());

Output

Name
Eduardo
undefined
{
  getName: [Function: getName],
  setName: [Function: setName],
  saveName: 'TEST'
}
Eduardo

¿Por qué es privado? poque basicamente lo que retorna es una objeto con los dos metodos, pero con el ambito de la funcion persona.

el objeto retornado no tienen la propiedad saveName. Es por esto que es undefined.

Esto me recuerda bastante a las clases de JS en Programación Orientada a objetos, de hecho me aclaro algunas dudas de dicho paradigma, aquí les dejo un enlace sobre campos privados en las clases (aceptadas en el ECMAScript 2015), solo como dato para saber que los campos privados ya se encuentran en propuesta experimental.

https://developer.mozilla.org/es/docs/Web/JavaScript/Referencia/Classes/Private_class_fields

Buena clase, sigo aprendiendo bastante. 👦🏻

Todo este tema me sonaba a una forma de emular el comportamiento de un objeto. Con esta clase ya quedó bastante claro que así es

Lo visto en esta clase en particular es similar a los métodos getters y setters de la programación orientada a objetos, Si has trabajado con clases y has manejado los atributos privados con métodos, se te facilitará.

Me recordó no solo al use State de react si no que a la POO en C++, donde puedes tener tus variables encapsuladas en una region privada y solo tener acceso a ellas mediante funciones dentro de la clase

Por alguna razón me recordó al state de react…

Buen dia campeon, cuando se declara una variable sin var, let y const; por defecto javascipt lo declara como variable global, y puede ser reasignada. dentro de un bloque de codigo como variable local. Asi es…

espero estar en lo correto, y si no!, que alguien argumente mi aporte, con una respuesta solida.

uff me encanta ver como entre nosotros los estudiantes nos aclaramos tantas dudas.

const person =()=>{
  var saveName='Name';//Variable privada
  return{//Get y Set funcionan como "intermediarios", para manipular la variable name
    getName: ()=>{//get
      return saveName;//Esta funcion nos permite saber el valor de saveName
    },
    setName:(name)=>{//set
      saveName=name;//Establecemosun nuevo valor por medio del parametro recibido
    }
  }
}

newPerson = person();//Creamos una variable que nos permite acceder al person
console.log(newPerson.getName());//obtenemos el valor actual de la variable por get
newPerson.setName('Hernando');//Con setName establecemos el nuevo valor 
console.log(newPerson.getName());//Revisamos el nuevo valor

Complemento para aprender a utilizar los getters y setters propios de JavaScript
//–
https://yeisondaza.com/entendiendo-getters-y-setters-en-javascript

Si alguno esta algo perdido con esta explicacion en MDN
hay una explicacion mas grafica, que explica de una manera mas simplificada y visual como funcionan los closures

Mi comprensión del tema

let test = () => {
    let test1 = 'Esto es una prueba';
    return{
        obt: () => {
            return test1;
        },
        dec: (mes) => {
            test1 = mes;
        }
    };
};

newtest = test();
console.log(newtest.obt());
newtest.dec('Esto es otro mensaje de prueba');
console.log(newtest.obt());```

Una pequena prueba intentando a acceder a las variable encapsulada saveName, por fuera de person.

const person = () => {
    var saveName = "Name";

    const getName = () => {
        return saveName;
    }

    const setName = (name) => {
        saveName = name;
    }

    return {
        getName,
        setName
    }
}

let newPerson = person();
console.log(newPerson.getName());
newPerson.setName('paola');
console.log(newPerson.getName());

// intentando ingresar a saveName 
console.log('aaa ', newPerson.saveName);
console.log('bbbb ', person().saveName);

//output
Name
paola
aaa undefined
bbbb undefined

Por medio de los closure podemos tener valores privados, ya que JS no los fomentas este tipo de valores

Me genera una duda. Si es para crear variables privadas con el closure, porque cuando creo accedo directamente a la variable sin el get o el set funciona.

newPerson = person();
newPerson.saveName = 'Anibal';
console.log(newPerson.saveName);

Gracias por sacarme de la duda

Variables privadas dentro de Closures:
Cuando se crea un Closure, existe la posibilidad de crear variables privadas, puesto que la forma en que se accede a esas variables es por medio de un método o función. Y solo serán leídas y manipuladas por dichos métodos o funciones internos del closure.
·
Esto significa que se deben disponer de métodos que son los únicos que tienen acceso para la interacción con los valores o propiedades del closure

No entendí… ¿por qué usó getName y setName? como arrow functions, y de dónde sacó ese newPerson para decirle que es igual a la función person. osea entiendo que la incializa con ese valor, pero por qué??

Segun entiendo para hacer privado un elemento dentro de una función, solo basta con retornar el valor de la misma y este se almacena en la expresión de funcion,evitando ser reasignado; si no es a traves sus propios métodos.

VARIABLES PRIVADAS CON CLOSURES APUNTES

const person = () => {

    var saveName = "Name";
    //utilizamos un return para retornar un objeto y creamos el atributo getname
    // el cual utilizamos con una funcion que retornara nuestra variable saveName
    return{

        getName: () =>{

            return saveName;

        },
//creamos  un nuevo atributo al cual le agregamos una funcion la cual recibe el
// parametro nombre
        setName:(name) =>{

            saveName = name;

        },

    };

};
//asigamos la funcion a una variable
let newPerson = person()
// imprimimos la variable junto con la funcion getname establecida en la funcion
console.log(newPerson.getName()) //Name valor que se encuentra almacenada en var saveName
// utilizamos newPerson con la funcion setName
newPerson.setName('andres'); // Le asignamos un nuevo valor con el setname
// Imprimimos la funcion junto con el get name
console.log(newPerson.getName())

//No podremos cambiar desde otro lado de la aplicacion si no que tendremos
// Que disponer de los metodos creados para disponer de estas asignaciones
// De esta forma estamos creando un valor privado

Bueno, para hacerlo mas dinámico, use POO, espero les sea útil si quieren practicar con ello y también entenderlo

class Person {

  constructor() {
    this.name = "Andres";
  }

  getName() {
    return this.name;
  }

  setNewName(otherName) {
    this.name = otherName;
  }
}

// Intanciando la clase Person

const newPerson = new Person();

console.log(newPerson.getName());
newPerson.setNewName("Carlos");
console.log(newPerson.getName());

JS no maneja Datos privados, estos que solo son dentro de tales metodos y que nadie mas pueda acceder dentro de ellas, pero se pueden crear algunas gracias a los Closures. Gracias a metodos podremos ver o modificar algunas variables pero nunca lo podremos hacer desde afuera.

const person = () => {
    var saveName = "Name"
    return {
        getName: () => {
            return  saveName;
        },
        setName: (name) => {
            saveName = name;
        },
    };
};

newPerson = person();
console.log(newPerson.getName());
newPerson.setName("Joel");
console.log(newPerson.getName());
newPerson.setName("Oscar");
console.log(newPerson.getName());

Como ven este codigo, necesitamos usar los metodos para poder asignar o poder tomar este valor. No podemos hacerlo directamente porque nos marcaria error. Asi podemos crear esta variable privada.

Algo similar a lo que se hace en Java con los metodos set y get para modificar las propiedades de una clase. Me confundía esto en JavaScript por la sintaxis de como se hace.

A ver si con esto se puede entender un poco la idea, copine y peguen el codigo! PlatziSalu2!

const person = () => {
// declarada como variable privada : no se puede cambiar su valor desde otro lado de la app, se neceitan otros metodos para ello como ahora con el setName!
var saveName = “Name”;
return {
getName: () => {
return saveName;
},
setName: (name) => {
saveName = name;
},
};
};

// aca ejecuto por primea ver el llamado de la funcion lo cual imprime el valor privado name.
newPerson = person();
console.log(newPerson.getName());

// le paso el valor a la fucion person el cual ira dentro de saveName, el cambio es solo para este llamado.
newPerson.setName(‘Mario Kaito Zubieta’);
console.log(newPerson.getName());

newPerson.setName(‘Jorge Zubieta’);
console.log(newPerson.getName());

//Llamo a la funcion nuevamente sin pasarle ningun dato y vemos que el dato de la variable inicial sigue como fue inicializado en forma privada, y no fue sobreescrito!
newPerson = person();
console.log(newPerson.getName());

8.-Cómo crear variables privadas con closures

JS no fomenta el uso de datos privados, pero por medio de closures podemos crear valores que solo se pueden acceder mediante métodos y que no van a estar disponibles fuera de esta función.

Los clousures los pueden ver como una especie de clase primitiva.

estos son los famosos getters y setters?

const person = () => {
    var saveName = "Pedro";
    return {
        getName: () => {
            return saveName;
        }, 
        setName: (name) => {
            saveName = name;
        },
    };
};

newPerson = person();
console.log(newPerson.getName()); // Pedro.
newPerson.setName('Carlos'); // Se sobre escribe la variable saveName con "Carlos".
console.log(newPerson.getName()); // Se pregunta el nombre de la variebla saveName que ya fue sobre escrita```

Asi fue como pude agregar otros valores usado clousure

Cómo crear variables privadas con closures
JavaScript por su naturaleza no fomenta datos privados, pero por medio de los closure podemos crear valores que solo pueden ser accedidos por medio de métodos que no van a estar disponible por fuera de esta función.

“hola mundo desde typeScript” …

Hice el mismo ejemplo solo que en lugar de una variable para el nombre, hice uso de un objeto con mas atributos.

const eliezer = {
	nombre: "Eliezer",
	edad: 26,
}

function crearPersona(persona){
    const newPersona = {
        ...persona,
    }
    return {
            cambiarNombre: (nombre) => {
                newPersona.nombre = nombre
            },
            obtenerNombre: () =>{
                return newPersona.nombre
            },
            cambiarEdad: (edad) => {
                newPersona.edad = edad
            },
            obtenerEdad: () => {
                return newPersona.edad
            }
           }
}

const newEliezer = crearPersona(eliezer)
newEliezer.obtenerNombre()
newEliezer.cambiarNombre("Ale")
newEliezer.obtenerNombre()

es algo confuso, pero, bueno. con let hice la prueba y funcionó muy bien!

const person = () => {
    let saveName = "Name";
    // Se declara la variable con let justo en la raíz de la función para que pueda ser vista en todos los niveles interiores.
    return {// Se retorna un "objeto" con 2 "metodos" (funciones)
        get name () {return saveName},
        // método 1, que no recibe parámetros y sólo devuelve la variable nombre.
        set name (name) {
        // método 2, que recibe un parámetro y lo asigna a la propiedad nombre definida en la raíz de este objeto.
        saveName = name;
        },
    };
};
// Define la constante mipersona y le asigna el objeto (la función) persona, recibiendo asi los 2 métodos (obtenerNombre y definirNombre).
const newPerson = person()
// Te dará el valor por omisión que en este caso sería sin nombre.
console.log(newPerson.name)
// Asignas un nuevo nombre.
newPerson.name = 'Max'
// Te dará el nuevo valor que asignaste la línea anterior.
console.log(newPerson.name)

Uso practico de los closures

//HTML
<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Uso practico de Closure</title>
    <style>
        body {
            display: flex;
            justify-content: center;
            flex-direction: column;
            font-family: Arial, Helvetica, sans-serif;
            font-size: 12px;
        }
        
        .texto {
            width: 80%;
            height: 300px;
            background-color: cadetblue;
        }
        
        h1 {
            font-size: 1.5em;
        }
        
        h2 {
            font-size: 1.2em;
        }
        
        a {
            display: block;
            width: 50px;
            height: 25px;
            background-color: black;
            color: azure;
            border: 1px solid white;
            font-size: 20px;
        }
    </style>
</head>

<body>
    <div class="texto">
        <h1>Este es un titulo de primer nivel</h1>
        <h2>Este es un titulo de segundo nivel</h2>
    </div>
    <div style="display: flex">
        <a href="#" id="size-12">12</a>
        <a href="#" id="size-14">14</a>
        <a href="#" id="size-16">16</a>
    </div>
    <script src="./index.js"></script>
</body>

</html>
//JavaScript
const makeSizer = (size) => () => (document.body.style.fontSize = size + "px");

let size12 = makeSizer(12);
let size14 = makeSizer(14);
let size16 = makeSizer(16);

document.getElementById("size-12").addEventListener("click", size12);
document.getElementById("size-14").addEventListener("click", size14);
document.getElementById("size-16").addEventListener("click", size16);

Cómo crear funciones privadas con closures

const Counter = () => {
    var privateCounter = 0; // variable privada
    //función privada
    function changeBy(val) {
        privateCounter += val;
    }
    return {
	//Estas tres funciones públicas son closures que comparten el mismo entorno. 
       //Gracias al ámbito léxico de Javascript, cada uno de ellas tienen acceso a la variable 
      //privateCounter y a la función changeBy.
        increment: function() {
            changeBy(1);
        },
        decrement: function() {
            changeBy(-1);
        },
        value: function() {
            return privateCounter;
        },
    };
};
const newCounter = Counter();
console.log(newCounter.value()); /* Muestra 0 */
newCounter.increment();
newCounter.increment();
console.log(newCounter.value()); /* Muestra 2 */
newCounter.decrement();
console.log(newCounter.value()); /* Muestra 1 */

JavaScript por su naturaleza no fomenta el uso de datos privados. Pero gracias a los closures podemos acceder a ciertos valores que solo pueden ser accedidos por medio de métodos y que no estarán disponibles fuera del scope de la función. Veremos cómo podremos manejar datos privados en las funciones a través de closures.

Para esto vamos a crear una función, y por dentro esta va a tener métodos con los cuales podremos acceder al valor de una variable o asignarle algún valor, pero desde dentro del scope de la función, nunca desde afuera.

  1. Generamos nuestra función y dentro del scope global de la función declararemos la variable saveName (que en este caso guarda un valor por defecto) y luego vamos a retornar los métodos que vamos a utilizar para poder acceder a la variable saveName desde afuera.
  2. Para retornar estos métodos utilizaremos return y abriremos llaves. El método getName será una función que va a retornar el valor que se encuentra en la variable global. Y el método setName será una función que recibirá como parámetro el nuevo valor que le asignaremos a la variable global.
  3. Como estamos trabajando con closures, crearemos una nueva variable que recibirá como valor la función person y asignándole los métodos propios de esta función podemos acceder a los valores de esta variable e incluso modificarla.
//1 Creamos la función a la cual podremos acceder a los datos privados
const person = () => {
	//1.1 Declaramos la variable en el scope global de la función, a la cual
	//podremos acceder a su valor a través de los métodos (solo su valor)
  let saveName = "Sebastian";
	//1.2 Retornaremos los siguientes métodos al ejecutar la función 
	//para que a través de otras variables podamos usar estos métodos
  return {
		//1.2.1 Este método retornará el valor de la variable global
    getName: () => {
      return saveName;
    },
		//1.2.2 Este método podrá cambiar el valor con el parámetro que le pasemos
    setName: (name) => {
      saveName = name;
    },
  };
};

//2. Creamos la variable que ejecutará la función al ser llamada
const newPerson = person();
//2.1 Imprimimos el valor de la variable actual en la consola (Sebastian) 
console.log(newPerson.getName());
//2.2 Ahora asignaremos un nuevo valor a la variable saveName 
newPerson.setName("GuilEsmit");
//2.3 Imprimimos en consola el valor de la variable saveName actualizado
console.log(newPerson.getName());

// Sebastian
// GuilEsmit

No podemos reasignar ni imprimir el valor de saveName si no es a través de los métodos que acabamos de crear. Así es como podemos generar una propiedad o un valor que es privada y no tenemos acceso a ellas, y de esta forma es como trabajamos con los closures para acceder a estos datos.

Cómo crear variables privadas con closures

Esta es la forma de hacer privada una variables y luego poder acceder a ella mediante metodos getter y setter.

en el retorno de la función principal, se hacen las dos funciones que van a obtener la variable get y que van a configurar la variable set , así de esta forma podremos acceder a la variable y configurarla

const person = () => {
  var saveName = 'Name'
  return {
    getName: () => {
      return saveName
    },
    setName: (name) => {
      saveName = name
    }
  }
}

newPerson = person()
console.log(newPerson.getName()) // --> Name
newPerson.setName('Oscar')
console.log(newPerson.getName()) // --> Oscar
const person = () => {
   var saveName = 'Name ay vee';
   return {
       getName: () => {
           return saveName;
       },
       setName: (name) => {
           saveName = name;
       },
   }; 
};

newPerson = person();

console.log(newPerson.getName());
newPerson.setName('Johan el ojaldre');
console.log(newPerson.getName());

/* Asi creamos variable pribadas utilizando closures, lo que hace al retornar el objeto dentro de la funcion person, es dar la opcion de modificar la variable saveName por medio de la funcion setName(name), esto hace que nuestros datos sean privados y que para acceser a ellos sea necesario utilizar los metodos que se encuentran en nuestro objeto ya que de otra forma no va a ser posible asignarle un valor diferente a  saveName */

Esto es equivalente a una clase, verdad?

En qué casos se utiliza un clousure en lugar de clases?

Muy buena clase =)

en pocas palabras esto seria como usar getters y seters

Genial!

Si quieren ver explicado más a detalle lo de las variables privadas, les recomiendo este enlace ⚡⚡⚡

Mis apuntes con su explicación:

function person() {
  var saveName = 'Name';  // Inicializa la variable con un valor por defecto
  return { // Closure de métodos (objeto con sus atributos)
    getName: () => {  // Atributo que retornará el nombre
      return saveName;
    },
    setName: (name) => {  // Atributo que contendrá el nombre
      saveName = name;
    }
  };
};

var newPerson = person()  // Almanena el contenido de la función person, es decir, la inicialización de la variable por defecto y el objeto para manejar los métodos.

console.log(newPerson.getName());  // Al ser el método un atributo de un objeto se maneja como tal.
newPerson.setName('Jhean');
console.log(newPerson.getName());

Variables privadas
Normalmente JS no nos da la opción de modificar un acceso como en otros lenguajes, pero con un closure podemos hacerlo, tendremos nuestras variables en el entorno y esta vez en vez de retornar una función retornaremos un objeto con múltiples de estas para tener varias funciones disponibles las cuales serán getters y setters de nuestras variables como:

const padre = () => {
	var variablePrivada = 0;
	const Acceso = {
		getVariable: function(){return variablePrivada;},
		setVariable: function(nuevoValor){variablePrivada = nuevoValor;}
	};
};
let miAcceso = padre();
miAcceso.getVariable();

Esto es así porque debido al scope a esas variables no se pueden utilizar, pero gracias a un closure si se puede 😃

Genial, es una forma bastante buena de tener datos privados en Javascript

const employee = () => {
  let name;
  let age;
  
  const setName = (value) => {
  	name =  value;
  }
  
  const getName = () =>{
  	return name;
  }
  
  const setAge = (value) => {
  	age =  value;
  }
  
  const getAge = () =>{
  	return age;
  }
  
  return {
   setName,
    getName,
    setAge,
    getAge
  }
  
  
}

let newEmployee = employee();

newEmployee.setName("German");
newEmployee.setAge(25);
console.log(newEmployee.getName()); // "German"
console.log(newEmployee.getAge()); // 25

Proteger el acceso a las variables es el primer uso que tienen los closures.

Cuando declaras una variable con “var” esa variable pasará a ser una propiedad del objeto global window. EJ:
El profesor declaró una variable llamada newPerson, pero no le colocó la palabra reservada var, let o const. Cuando se declara una variable de esta manera, es como si estuvieramos declarando la variable con var, por ende pasaría a ser una propiedad del objeto globlal window.

Le encuentro mucha similitud a clases y objetos con sus propiedades y comportamientos. De hecho, creo que se puede hacer el mismo tipo de programación.

No he entendido nada xD

me parece interesante que también se puede poner privada metodos de esa función

  var Counter = (function() {
    var privateCounter = 0;
    function changeBy(val) {
      privateCounter += val;
    }
    return {
      increment: function() {
        changeBy(1);
      },
      decrement: function() {
        changeBy(-1);
      },
      value: function() {
        return privateCounter;
      }
    }
  })();
  
  console.log(Counter.value()); /* Muestra 0 */
  Counter.increment();
  Counter.increment();
  console.log(Counter.value()); /* Muestra 2 */
  Counter.decrement();
  console.log(Counter.value()); /* Muestra 1 */ ```

¿Cuando puedo utilizar las variables privadas?
algunos ejemplos en proyectos por favor.

¿Estos son prototipos ?

madre mía, qué es todo estooooo