Curso de Closures y Scope en JavaScript

Practicando Closures

Curso de Closures y Scope en JavaScript

Contenido del curso

Bienvenida

  • 1
    Bienvenida al Curso de Closures y Scope

    Bienvenida al Curso de Closures y Scope

    01:11 min

Tipos de scope en JavaScript

  • 2
    Global Scope

    Global Scope

    12:09 min
  • 3
    Function Scope

    Function Scope

    05:52 min
  • 4
    Block Scope

    Block Scope

    07:16 min
  • 5
    Reasignación y redeclaración

    Reasignación y redeclaración

    14:05 min
  • 6
    Strict Mode

    Strict Mode

    05:54 min

Closure

  • 7
    ¿Qué es un Closure?

    ¿Qué es un Closure?

    09:37 min
  • 8
    Practicando Closures

    Practicando Closures

    Viendo ahora

Hoisting

  • 9
    ¿Qué es el Hoisting?

    ¿Qué es el Hoisting?

    08:28 min

Debugging

  • 10
    Debugging

    Debugging

    04:33 min

Cierre

  • 11
    Conclusiones

    Conclusiones

    03:23 min
schoolTomar examen
search
CursosEmpresasBlogLiveConfEventosPrecios

0:00/15:24

Practicando Closures

Curso de Closures y Scope en JavaScript

Clase 8 de 11

Clase 8 / 11

Progreso del curso

Bienvenida

  • 1

    Bienvenida al Curso de Closures y Scope

    01:11

Tipos de scope en JavaScript

  • 2lock

    Global Scope

    Suscríbete para ver más
  • 3lock

    Function Scope

    Suscríbete para ver más
  • 4lock

    Block Scope

    Suscríbete para ver más
  • 5lock

    Reasignación y redeclaración

    Suscríbete para ver más
  • 6lock

    Strict Mode

    Suscríbete para ver más

Closure

  • 7lock

    ¿Qué es un Closure?

    Suscríbete para ver más
  • play_arrowlock

    Practicando Closures

    play_circleViendo ahora

Hoisting

  • 9lock

    ¿Qué es el Hoisting?

    Suscríbete para ver más

Debugging

  • 10lock

    Debugging

    Suscríbete para ver más

Cierre

  • 11lock

    Conclusiones

    Suscríbete para ver más
workspace_premiumTomar examen

Escuelas

  • Desarrollo Web
    • Fundamentos del Desarrollo Web Profesional
    • Diseño y Desarrollo Frontend
    • Desarrollo Frontend con JavaScript
    • Desarrollo Frontend con Vue.js
    • Desarrollo Frontend con Angular
    • Desarrollo Frontend con React.js
    • Desarrollo Backend con Node.js
    • Desarrollo Backend con Python
    • Desarrollo Backend con Java
    • Desarrollo Backend con PHP
    • Desarrollo Backend con Ruby
    • Bases de Datos para Web
    • Seguridad Web & API
    • Testing Automatizado y QA para Web
    • Arquitecturas Web Modernas y Escalabilidad
    • DevOps y Cloud para Desarrolladores Web
  • English Academy
    • Inglés Básico A1
    • Inglés Básico A2
    • Inglés Intermedio B1
    • Inglés Intermedio Alto B2
    • Inglés Avanzado C1
    • Inglés para Propósitos Específicos
    • Inglés de Negocios
  • Marketing Digital
    • Fundamentos de Marketing Digital
    • Marketing de Contenidos y Redacción Persuasiva
    • SEO y Posicionamiento Web
    • Social Media Marketing y Community Management
    • Publicidad Digital y Paid Media
    • Analítica Digital y Optimización (CRO)
    • Estrategia de Marketing y Growth
    • Marketing de Marca y Comunicación Estratégica
    • Marketing para E-commerce
    • Marketing B2B
    • Inteligencia Artificial Aplicada al Marketing
    • Automatización del Marketing
    • Marca Personal y Marketing Freelance
    • Ventas y Experiencia del Cliente
    • Creación de Contenido para Redes Sociales
  • Inteligencia Artificial y Data Science
    • Fundamentos de Data Science y AI
    • Análisis y Visualización de Datos
    • Machine Learning y Deep Learning
    • Data Engineer
    • Inteligencia Artificial para la Productividad
    • Desarrollo de Aplicaciones con IA
    • AI Software Engineer
  • Ciberseguridad
    • Fundamentos de Ciberseguridad
    • Hacking Ético y Pentesting (Red Team)
    • Análisis de Malware e Ingeniería Forense
    • Seguridad Defensiva y Cumplimiento (Blue Team)
    • Ciberseguridad Estratégica
  • Liderazgo y Habilidades Blandas
    • Fundamentos de Habilidades Profesionales
    • Liderazgo y Gestión de Equipos
    • Comunicación Avanzada y Oratoria
    • Negociación y Resolución de Conflictos
    • Inteligencia Emocional y Autogestión
    • Productividad y Herramientas Digitales
    • Gestión de Proyectos y Metodologías Ágiles
    • Desarrollo de Carrera y Marca Personal
    • Diversidad, Inclusión y Entorno Laboral Saludable
    • Filosofía y Estrategia para Líderes
  • Diseño de Producto y UX
    • Fundamentos de Diseño UX/UI
    • Investigación de Usuarios (UX Research)
    • Arquitectura de Información y Usabilidad
    • Diseño de Interfaces y Prototipado (UI Design)
    • Sistemas de Diseño y DesignOps
    • Redacción UX (UX Writing)
    • Creatividad e Innovación en Diseño
    • Diseño Accesible e Inclusivo
    • Diseño Asistido por Inteligencia Artificial
    • Gestión de Producto y Liderazgo en Diseño
    • Diseño de Interacciones Emergentes (VUI/VR)
    • Desarrollo Web para Diseñadores
    • Diseño y Prototipado No-Code
  • Contenido Audiovisual
    • Fundamentos de Producción Audiovisual
    • Producción de Video para Plataformas Digitales
    • Producción de Audio y Podcast
    • Fotografía y Diseño Gráfico para Contenido Digital
    • Motion Graphics y Animación
    • Contenido Interactivo y Realidad Aumentada
    • Estrategia, Marketing y Monetización de Contenidos
  • Desarrollo Móvil
    • Fundamentos de Desarrollo Móvil
    • Desarrollo Nativo Android con Kotlin
    • Desarrollo Nativo iOS con Swift
    • Desarrollo Multiplataforma con React Native
    • Desarrollo Multiplataforma con Flutter
    • Arquitectura y Patrones de Diseño Móvil
    • Integración de APIs y Persistencia Móvil
    • Testing y Despliegue en Móvil
    • Diseño UX/UI para Móviles
  • Diseño Gráfico y Arte Digital
    • Fundamentos del Diseño Gráfico y Digital
    • Diseño de Identidad Visual y Branding
    • Ilustración Digital y Arte Conceptual
    • Diseño Editorial y de Empaques
    • Motion Graphics y Animación 3D
    • Diseño Gráfico Asistido por Inteligencia Artificial
    • Creatividad e Innovación en Diseño
  • Programación
    • Fundamentos de Programación e Ingeniería de Software
    • Herramientas de IA para el trabajo
    • Matemáticas para Programación
    • Programación con Python
    • Programación con JavaScript
    • Programación con TypeScript
    • Programación Orientada a Objetos con Java
    • Desarrollo con C# y .NET
    • Programación con PHP
    • Programación con Go y Rust
    • Programación Móvil con Swift y Kotlin
    • Programación con C y C++
    • Administración Básica de Servidores Linux
  • Negocios
    • Fundamentos de Negocios y Emprendimiento
    • Estrategia y Crecimiento Empresarial
    • Finanzas Personales y Corporativas
    • Inversión en Mercados Financieros
    • Ventas, CRM y Experiencia del Cliente
    • Operaciones, Logística y E-commerce
    • Gestión de Proyectos y Metodologías Ágiles
    • Aspectos Legales y Cumplimiento
    • Habilidades Directivas y Crecimiento Profesional
    • Diversidad e Inclusión en el Entorno Laboral
    • Herramientas Digitales y Automatización para Negocios
  • Blockchain y Web3
    • Fundamentos de Blockchain y Web3
    • Desarrollo de Smart Contracts y dApps
    • Finanzas Descentralizadas (DeFi)
    • NFTs y Economía de Creadores
    • Seguridad Blockchain
    • Ecosistemas Blockchain Alternativos (No-EVM)
    • Producto, Marketing y Legal en Web3
  • Recursos Humanos
    • Fundamentos y Cultura Organizacional en RRHH
    • Atracción y Selección de Talento
    • Cultura y Employee Experience
    • Gestión y Desarrollo de Talento
    • Desarrollo y Evaluación de Liderazgo
    • Diversidad, Equidad e Inclusión
    • AI y Automatización en Recursos Humanos
    • Tecnología y Automatización en RRHH
  • Finanzas e Inversiones
    • Fundamentos de Finanzas Personales y Corporativas
    • Análisis y Valoración Financiera
    • Inversión y Mercados de Capitales
    • Finanzas Descentralizadas (DeFi) y Criptoactivos
    • Finanzas y Estrategia para Startups
    • Inteligencia Artificial Aplicada a Finanzas
    • Domina Excel
    • Financial Analyst
    • Conseguir trabajo en Finanzas e Inversiones
  • Startups
    • Fundamentos y Validación de Ideas
    • Estrategia de Negocio y Product-Market Fit
    • Desarrollo de Producto y Operaciones Lean
    • Finanzas, Legal y Fundraising
    • Marketing, Ventas y Growth para Startups
    • Cultura, Talento y Liderazgo
    • Finanzas y Operaciones en Ecommerce
    • Startups Web3 y Blockchain
    • Startups con Impacto Social
    • Expansión y Ecosistema Startup
  • Cloud Computing y DevOps
    • Fundamentos de Cloud y DevOps
    • Administración de Servidores Linux
    • Contenerización y Orquestación
    • Infraestructura como Código (IaC) y CI/CD
    • Amazon Web Services
    • Microsoft Azure
    • Serverless y Observabilidad
    • Certificaciones Cloud (Preparación)
    • Plataforma Cloud GCP

Platzi y comunidad

  • Platzi Business
  • Live Classes
  • Lanzamientos
  • Executive Program
  • Trabaja con nosotros
  • Podcast

Recursos

  • Manual de Marca

Soporte

  • Preguntas Frecuentes
  • Contáctanos

Legal

  • Términos y Condiciones
  • Privacidad
  • Tyc promociones
Reconocimientos
Reconocimientos
Logo reconocimientoTop 40 Mejores EdTech del mundo · 2024
Logo reconocimientoPrimera Startup Latina admitida en YC · 2014
Logo reconocimientoPrimera Startup EdTech · 2018
Logo reconocimientoCEO Ganador Medalla por la Educación T4 & HP · 2024
Logo reconocimientoCEO Mejor Emprendedor del año · 2024
De LATAM conpara el mundo
YoutubeInstagramLinkedInTikTokFacebookX (Twitter)Threads

Comentarios (169)169 comentarios

Recursos

Ahora que ya entiendes qué es un closure, te mostraré un ejemplo para emplearlo en un proyecto.

Cómo utilizar Closure para construir una alcancía

Si creamos una alcancía de la siguiente manera, solamente mostrará el valor enviado, no guardará la información del dinero que le enviamos.

function alcancia(monedas){ let contenido = 0 contenido = contenido + monedas return contenido } const miAlcancia = alcancia miAlcancia(5) // 5 miAlcancia(4) // 4

Si utilizamos un closure, entonces la variable en que estará en un scope más elevado que la función interior, recordará el ámbito léxico que fue creada. Por lo tanto, cada vez que invoquemos cada función, mostrará el dinero ahorrado en la alcancía.

function alcancia(cantidadInicial){ let contenido = cantidadInicial return function guardar(monedas){ contenido = contenido + monedas return contenido } } const miAlcancia = alcancia(2) miAlcancia(5) // 7 miAlcancia(4) // 11 const otraAlcancia = alcancia(5) otraAlcancia(30) // 35 otraAlcancia(20) // 55

Contribución creada por Andrés Guano.

José Isidro Torres Caldea

José Isidro Torres Caldea

Hace 4 años
    César Palma

    César Palma

    Hace 4 años
Juan Esteban Perdomo Santos

Juan Esteban Perdomo Santos

Hace 4 años
    Raycris Maldonado

    Raycris Maldonado

    Hace 4 años
    Nestor Rios Garcia

    Nestor Rios Garcia

    Hace 4 años
Kevin Zavala

Kevin Zavala

Hace 4 años
    Beder Danilo Casa Condori

    Beder Danilo Casa Condori

    Hace 2 años
Orlando Rodriguez

Orlando Rodriguez

Hace 4 años
    Emerson David Cabrera Salas

    Emerson David Cabrera Salas

    Hace 4 años
    Eliezer Hernandez

    Eliezer Hernandez

    Hace 4 años
Kevin J. Zea Alvarado

Kevin J. Zea Alvarado

Hace 4 años
    WALT 🤖

    WALT 🤖

    Hace 4 años
    Alejandro López Aguilar

    Alejandro López Aguilar

    Hace 3 años
Aranxa Martinez

Aranxa Martinez

Hace 4 años
    José Eras

    José Eras

    Hace 4 años
    Aranxa Martinez

    Aranxa Martinez

    Hace 4 años
Larry Finol

Larry Finol

Hace 4 años
Juan Pablo Ospina Restrepo

Juan Pablo Ospina Restrepo

Hace 4 años
    Humberto Asca

    Humberto Asca

    Hace 4 años
Stiven Andres Medina Lopez

Stiven Andres Medina Lopez

Hace 4 años
    Nestor Rios Garcia

    Nestor Rios Garcia

    Hace 4 años
    Diego Zazueta

    Diego Zazueta

    Hace 2 años
Luis Carlos Zapata García

Luis Carlos Zapata García

Hace 4 años
Juan Reyes

Juan Reyes

Hace 4 años
Dario Paladines

Dario Paladines

Hace 4 años
    Fernando Alejandro Yerena Ramos

    Fernando Alejandro Yerena Ramos

    Hace 4 años
Josué Jairo Quichca Álvarez

Josué Jairo Quichca Álvarez

Hace 4 años
    Oscar Barajas Tavares

    Oscar Barajas Tavares

    Team Platzi
    Hace 4 años
    Andres Prieto

    Andres Prieto

    Hace 4 años
Santiago Andres Alvarez Cuadros

Santiago Andres Alvarez Cuadros

Hace 4 años
Rubén Cuello

Rubén Cuello

Hace 4 años
Andres Alvarez Becerra

Andres Alvarez Becerra

Hace 4 años
    Brandon Gomez

    Brandon Gomez

    Hace 4 años
Tomas Pucutay

Tomas Pucutay

Hace 4 años
    David Hereira

    David Hereira

    Hace 4 años
Eduardo Romero

Eduardo Romero

Hace 4 años
Jesús León

Jesús León

Hace 4 años
    Ismael Cruz Procel

    Ismael Cruz Procel

    Hace 4 años
Juan Luis Medina Coelho

Juan Luis Medina Coelho

Hace 4 años
    silfredo mario

    silfredo mario

    Hace 4 años

¡Adiós al var! . Con esta técnica de Closures ya nos podemos evitar totalmente el uso de la palabra reservada var, ya no necesitamos una variable que sea global para almacenar un valor que vamos a usar/modificar dentro de alguna función o bloque, ahora podemos manejar y controlar una variable que solo existe dentro de la función que la va a modificar, limitando su alcance podemos evadir errores lógicos ya que si en otra función tenemos una variable con el mismo nombre, no afectará nuestra lógica y no nos dará resultados inesperados, porque literalmente será otra variable, independiente de la que creamos en nuestra primera función. 😌 . ¿Y qué pasa si yo creo una variable dentro de una función y también la quiero usar en otra función? 😰 Tranqui... existe la palabra reservada return que nos ayudará a extraer el valor de nuestra variable y colocarla en otro contexto o alcance. . Con cada clase, Oscar nos va mostrando la manera correcta de programar para no caer en malas prácticas. 👨🏽‍🏫

"En javascript las funciones son ciudadanos de primera clase". Esta frase que la escuché hace mucho tiempo es algo que se debe tener en cuenta al crear nuestro programas.

Este es mi ejemplo. :)

const maestro = "Dios"; function crearFamilia() { const abuela = "carlina"; function hijosAbuela() { const hijoOne = "Martha"; const hijoTwo = "Evelio"; const hijoThree = "Rocio"; function hijosDeHijosAbuela() { const hijosRocio = [{ nombre: "juan" }, { nombre: "andrea" }]; const hijosMatha = [{ nombre: "Fabian" }, { nombre: "Heidy" }]; const hijosEvelio = [ { nombre: "Nathy" }, { nombre: "Juancho" }, { nombre: "Santiago" }, ]; return { generacion: function () { console.log(` ${maestro} crea a mi abuela ${abuela} la abuela tuvo 3 hijos ${hijoOne} ${hijoTwo} ${hijoThree} los hijos de la abuela tienen hijos. Rocio: ${hijosRocio[0].nombre} y ${hijosRocio[1].nombre} Martha: ${hijosMatha[0].nombre} y ${hijosMatha[1].nombre} Evelio: ${hijosEvelio[0].nombre} ${hijosEvelio[1].nombre} y ${hijosEvelio[2].nombre} `); }, }; } return hijosDeHijosAbuela(); } return hijosAbuela(); } const generar = crearFamilia(); console.log(generar.generacion());

Muy bien hecho Juan, pero para simplificar el código podrías haber hecho un map de los array de objetos y es mas fácil. ejemplo:

const maestro = "Dios"; function crearFamilia() { const abuela = "carlina"; function hijosAbuela() { const hijoOne = "Martha"; const hijoTwo = "Evelio"; const hijoThree = "Rocio"; function hijosDeHijosAbuela() { const nietos = [ { hijosRocio1: "juan", hijosRocio2: "andrea", hijosMatha1: "Fabian", hijosMatha2: "Heidy", hijosEvelio1: "Nathy", hijosEvelio2: "Juancho", hijosEvelio3: "Santiago", }, ]; return { generacion: function () { nietos.map((nieto) => { console.log( `${maestro} crea a mi abuela ${abuela} la abuela tuvo 3 hijos ${hijoOne}, ${hijoTwo}, ${hijoThree} los hijos de la abuela tienen hijos. Hijos de ${hijoThree}: ${nieto.hijosRocio1} y ${nieto.hijosRocio2}, Los hijos de ${hijoOne}: ${nieto.hijosMatha1} y ${nieto.hijosMatha2} y por ultimo tenemos a los hijos de ${hijoTwo} que son: ${nieto.hijosEvelio1}, ${nieto.hijosEvelio2} y ${nieto.hijosEvelio3}` ); }); }, }; } return hijosDeHijosAbuela(); } return hijosAbuela(); } const generar = crearFamilia(); console.log(generar.generacion());

Así sería la lógica un poquito más clara y entendible para mi, y un poco mas organizada, podría mejorar un poco más el código, pero sin embargo hiciste un buen trabajo. Saludos!

Algo revuelto, pero me encanto el ejemplo.

Les dejo este algoritmo que hace un bonito mosaico.

function mosaico() { const figuras = []; function pintar(nuevaFigura) { figuras.push(nuevaFigura); let resultado = ''; const mainLength = figuras.length * 2; for (let fila = 0; fila < mainLength; fila++) { for(let columna = 0; columna < mainLength; columna++) { const valorMax = fila > columna ? fila : columna; const valorMin = fila < columna ? fila : columna; const valorPosible = mainLength - (valorMax + 1); const indexFigura = valorPosible < valorMin ? valorPosible : valorMin; resultado += `${figuras[indexFigura]} `; } resultado += '\n'; } return resultado; } return pintar; } const m = mosaico(); console.log(m('*')); console.log(m('o')); console.log(m('+')); console.log(m('x'));
mosaico.png

me gusto este ejercicio

Me esta costando entender mucho este concepto, pero basandome en el ejercicio de myMoneyBox, pude crear este codigo que seria ir agregando articulos a un Carrito de compras, para una tienda en especifico.

function shoppingCart(){ let cart = []; function addItems(item){ cart.push(item); console.log(cart); } return addItems; } const amazon = shoppingCart(); amazon("Mouse"); amazon("Keyboard"); amazon(`Display 24"`);

Que opinan?

Está muy bueno tu ejemplo, de hecho, me sirve para encontrarle un uso real a los closures.

Excelente!!!. Ahora podras perfeccionar la idea para conocer los productos del carrito, o incluso eliminarlos. Podrías, en lugar de retornar directamente una función, retornar un objeto con métodos, ya que estos de igual manera recordaran el lexical environment exterior y seguiría siendo un closure.

function shoppingCart(){ let cart = [] return { addItems(item){ cart.push(item); }, getCartItem(){ return cart }, removeItem(){ cart.pop() } }; } const amazon = shoppingCart(); amazon.addItems("Mouse"); amazon.addItems("Keyboard"); amazon.addItems(`Display 24"`); amazon.getCartItem() // ['Mouse', 'Keyboard', 'Display 24"'] amazon.removeItem() amazon.getCartItem() // ['Mouse', 'Keyboard']

A mí se me ocurrió este ejemplo:

.

closure.png

La función moneyBox devuelve un objeto con funciones que «recuerdan» ownerName y totalMoney.

.

Además, agrego una manera en la que se pueden renombrar cada una de las funciones devueltas en el objeto retornado.

.

Espero que les sirva. 💚

excelente!

me ayudaste a conocer el concepto de sintaxis de destructuracion, muchas gracias!

¿Por qué se hace return a countCoins si es una función, y como es que al pasarle argumentos a moneyBox (el cual no tiene parametros) es como si los tomará la función countCoins?

Hace return a countCoins debido a que si es posible retornar funciones al igual que cualquier otro valor, entonces, se retorna countCoins (sin los parentesis) para que pueda ser ++invocada fuera de su contexo de ejecución++, por lo que realmente se pasa los argumentos a countCoins en lugar de a moneyBox.

const mb1 = moneyBox(); // retorna countCoins y se almacena en mb1. mb1(5); // ahora llamo countCoints que ha sido previamente almacenada en mb1 y le paso el 5 como parámetro.

Tomar en cuenta que en el return no está invocando la función, sino devolviendola para ser ejecutada fuera de su contexto de ejecución.

@jogaec Muchas gracias por tu respuesta! Me ayudaste mucho

Woou, tenía tiempo usando JavaScript de lo que había aprendido de forma autónoma, pero desde que entre a Platzi nunca paro de aprender nuevos conceptos y/o funcionalidades cómo las Closures

Quiero decir primero que todo que me ayude mucho mirando este video me ayudo a entender mas de como funcionan y como podemos implementarlos

CODE:

function moneyBox (){ let saveCoins = 0 ; return { depositar: function countCoins (coins){ saveCoins+=coins; }, retirar: function countCoins (coins){ saveCoins-=coins; }, saldo: function countCoins (){ return saveCoins } } } const moneyBoxAna = moneyBox(); console.log(moneyBoxAna.saldo()); moneyBoxAna.depositar(5); console.log(moneyBoxAna.saldo()); moneyBoxAna.retirar(1) console.log(moneyBoxAna.saldo());

RESULTADO:

resultEjemplosClosures.png

Gracias por compartir el enlace del video.

Posterior a ello busqué caso típicos del uso de closure y encontré este video interesante:

3 Ejemplos REALES de Closures en JavaScript

  • En JavaScript las funciones se pueden comportar como objetos, entonces los closures vendria a ser un tipo de funcion que tiene estados.

  • Para crear un closure tenemos que crear una funcion que retorne otra funcion

  • Los closures era la antigua forma de simular las clases en JavaScript

closure.png

Interesante información.

De hecho son dos conceptos diferentes es una combinacion de clousures con funciones tipo IIFE o funciones auto invocadas muy utilizadas para no contaminar el ambito o scope global, encapsular codigo o modularizar codigo.

Código ejemplo clase 8

function moneyBox(){ let saveCoins =0; functions countCoins(coins){ saveCoins +=coins; console.log( `MoneyBox: $${saveCoins}`) } return countCoins; } const myMoneyBox = moneyBox(); myMoneyBox(5); //ahorra 5 myMoneyBox(5); //ahorra 10 myMoneyBox(15) //ahorra 25

Mi ejemplo!

function family() { let family = []; function addMember(member) { family.push(member) console.log(`Esta familia está compuesta por ${family}`) } return addMember; } let petersFamily = family(); petersFamily('Peter'); petersFamily('Camille'); petersFamily('John'); let emilysFamily = family(); emilysFamily('Emily') emilysFamily('Carl') emilysFamily('Sophy')

La duda que me queda es porque guardamos en una variable la función global (const myMoneyBox = moneyBox()). Porqué simplemente no se ejecuta y se manda a llamar la función de forma tradicional y agregándole como parámetro las monedas => moneyBox(5). Aunque claro la función global no tiene ningún parámetro, por eso es que me surge la duda de porque agregarla a una constante y porque no sale de forma directa

Porque cuando ejecutas moneyBox() lo que estas retornando es una función, en este caso countCoins() y esta es la que recibe un parametro.

¿Por qué guardarla en una constante? Así podemos "instanciarla" varias veces y no sobreescibirla.

const myMoneyBox = moneyBox() const momMoneyBox = moneyBox() const brotherMoneyBox = moneyBox() myMoneyBox(7) // MoneyBox: 7 momMoneyBox(21) // MoneyBox: 21 brotherMoneyBox(13) // MoneyBox: 13

Cada uno mantiene su propio saveCoins.

Si lo ejecutamos directamente entonces ya no podríamos hacer más llamadas subsecuentes.

const myMoneyBox = moneyBox()(5) // MoneyBox: 13;

Si ahora intentarás guardar más monedas no se podría porque myMoneyBox nunca recibió una función.

myMoneyBox(2) // Uncaught TypeError: myMoneyBox is not a function

Y al ser una constante ya no podrías cambiar su valor.

Como es que countCoins logra obtener el parametro?? Ayuda porfavor

Cuentame mas sobre tu duda, no me queda claro.

Has este ejercicio y lo vas a entender:

function hola() { return function saluda(nombre) { console.log("Hola " + nombre) } } console.log(hola) // ⇒ Esta es una función

Acá está tu duda, sPOOiler

let saludador = hola() console.log(saludador) // ¿Qué te sale acá?

Confirmación

saludador("Platzi") // Output: // Hola Platzi

Adjunto mi aporte. Tomé la idea del carrito de compras del comentario de Ricardo Mejía y me puse a experimentar un poco con los métodos de arreglos del curso de manipulación de arrays hasta obtener el siguiente resultado:

function productos() { let agregarCarrito = []; function agregarProducto(producto) { let valorProducto = Number((Math.random()*10).toFixed(2)); agregarCarrito.push({ producto: producto, valor: valorProducto, }); } function eliminarProducto(producto){ const productoEliminado = agregarCarrito.find((value) => value.producto == producto); console.log(`Eliminaste '${productoEliminado.producto}' del carrito`); agregarCarrito.splice(agregarCarrito.findIndex(index => index.producto === producto), 1); total(); } function mostrarProductos(){ console.log(agregarCarrito.map((value) => `${value.producto}: $${value.valor}`)); } function total(){ let totalProductos = (agregarCarrito.reduce((sum, values) => sum + values.valor, 0)).toFixed(2); console.log(`El total del carrito es: $${totalProductos}`); console.log(''); } return { agregarProducto, eliminarProducto, mostrarProductos, total, }; } const carrito = productos(); carrito.agregarProducto('Galletas'); carrito.agregarProducto('Chocolate'); carrito.agregarProducto('Avena'); carrito.agregarProducto('Leche'); carrito.agregarProducto('Azúcar'); carrito.mostrarProductos(); carrito.total(); carrito.eliminarProducto('Chocolate'); carrito.eliminarProducto('Leche'); carrito.mostrarProductos(); carrito.agregarProducto('Arroz'); carrito.mostrarProductos(); carrito.total(); /*imprime: [ 'Galletas: $4.67', 'Chocolate: $1.34', 'Avena: $4.22', 'Leche: $2.76', 'Azúcar: $2.72' ] El total del carrito es: $15.71 Eliminaste 'Chocolate' del carrito El total del carrito es: $14.37 Eliminaste 'Leche' del carrito El total del carrito es: $11.61 [ 'Galletas: $4.67', 'Avena: $4.22', 'Azúcar: $2.72' ] [ 'Galletas: $4.67', 'Avena: $4.22', 'Azúcar: $2.72', 'Arroz: $7.88' ] El total del carrito es: $19.49*/

Muy ilustrativo. Siempre me pregunté como hacer para recordar valores acumulados. Ahora ya se como :smile:

Programación funcional

En este paradigma existe algo que se llama composición de funciones, closures y Currying.

Composición de funciones o funciones compuestas

Son el resultado de combinar 2 o más funciones, el resultado de cada función es el argumento de la siguiente y así sucesivamente

addOne(timesTwo(1))

Closure

Fue explicado la clase anterior

Currying

Gracias a los closures es posible implementar el Currying. Esto es descomponer funciones complejas en otras funciones más pequeñas donde cada función recibe un solo argumento.

// Sin Currying function sumThreeNumbers(a, b, c) { return a + b + c } console.log(sumThreeNumbers(1, 2, 3)) // 6 // Con Currying function sumThreeNumbers(a) { return function(b) { return function(c) { return a + b + c } } } console.log(sumThreeNumbers(1)(2)(3)) // 6

Disculpa, me suena como en el lenguaje prolog a las reglas. Es esto 🤨 o nada que ver?

Hice una modificación de prueba a la función de la clase para generar métodos específicos y así manipular las variables y protegerlas. Pueden ver un método actMoney (que muestra el dinero actual), rmvMoney (que es para retirar dinero) y addMoney (para agregar dinero).

'use strict' function moneyBox(initial){ let quantity = initial; console.log(`Your initial balance is ${quantity}`); return { addMoney: function(money){ quantity += money; console.log(`You added ${money}, your actual balance is: ${quantity}`); }, rmvMoney: function(money){ if (quantity < money) { console.log(`You can't withdraw ${money}. Not enough money`); } else { quantity -= money; console.log(`You withdrew ${money}, your actual balance is: ${quantity}`); } }, actMoney: function(){ console.log(`Your actual balance is: ${quantity}`); } } } const myMoney = moneyBox(100); myMoney.addMoney(100); myMoney.rmvMoney(200); myMoney.rmvMoney(100); myMoney.actMoney(); myMoney.addMoney(300);

No tenía idea que podia darsele este uso

Esto hace lo mismo pero con el return como una funcion llamada directamente

const moneyBox = () => { let saveCoins = 0; return (coins) => { saveCoins += coins; console.log(`MoneyBox: $${saveCoins}`); } } const myMoneyBox = moneyBox(); myMoneyBox(5); myMoneyBox(5); myMoneyBox(20); console.log('-----------------') const myMoneyBoxHector = moneyBox(); myMoneyBoxHector(10); myMoneyBoxHector(10);```

Es medio confuso el Block Scope si lo haces de manera strict y el ámbito léxico de los ++closure++. ¿Hay alguna manera de notar las diferencias para entender mejor?

Por lo general se que estamos hablando de un closure cuando tenemos 2 funciones anidadas y la función interna hace uso de variables de la externa, es decir que:

Tienes una closure cuando una función cualquiera accede a una variable fuera de su contexto.

Mientra más lo pienso menos sentido le encuentro a cómo funciona esto. No entiendo cómo logra sumar los saveCoins si literalmente la primera línea de la función está declarando e inicializando la variable a 0, ¿Cómo puede pasar eso por alto seguir sumando los valores anteriores??

O sea evidentemente pasa, el código corre y funciona perfectamente, solo me frustra no poder entender por qué 😥

Hola Juan.

Recuerda que las variables declaradas con la palabra reservada

let <code>

Sele pueden reasignar su valor. Por consiguiente ella inicia en 0, pero después sele dice que borre ese 0 y guarde un 5. Y posteriormente sele dice que ahora su valor no va a hacer 5, que en vez de eso va a hacer 5 + 10 o cualquier valor que sele este enviando.

Y esto se seguirá ejecutando cada vez que sele envíe un nuevo valor. Recuerda que cuando se usa **+= **se está diciendo que sele sume algo a lo que ya la variable tiene guardada y que ese sea su nuevo valor.

let ahorros = 5; ahorros += 10; // Si le haces un consolole.log a ahorros te arrojara 15 como resultado. <code>

Nota: Si saveCoins se hubiese hecho con la palabra reservada const, esto nunca pasaría, porque este tipo de variables, no permiten reasignar valores.