logo

midulive


Transcribed podcasts: 605
Time transcribed: 13d 3h 7m 36s

This graph shows how many times the word ______ has been mentioned throughout the history of the program.

Cuestión 1. Tenemos estas tres funciones. El click handler, el immediate y el delayed reload.
¿Cuál accede a una variable externa? Pues la primera seguro, ¿no? Porque el count clicks, pues esto es una externa.
Esta no, no está accediendo a ninguna externa. Y esta sí, porque esta es global. Ya está. Pues ahora tenemos. Vamos a ver.
La primera accede a la variable count clicks, que está en el scope externo.
Inmediate no accede a ninguna variable. Y la tercera, el scope global. Vale. Ok, perfecto. O sea que hasta aquí bien.
Cuestión 2. Los parámetros perdidos. ¿Qué es lo que va a loguear el siguiente snippet?
Esto es una función que se auto ejecuta, que le llega como parámetro el cero. O sea que immediate a la a es cero.
Este return, ya ves tú. Bueno, vale, esto es bastante claro. Esto es cero. No, no creo que sea undefined.
Es console.log es cero. Bueno, está bien porque parece muy complicada, pero una vez que la ves, dices, no, tampoco es tan difícil.
Porque, claro, se está haciendo así como complicada para intentar ver qué está pasando aquí, ¿no? De que no lo entiendas y tal.
Pero ahora entiendo que no. Está bastante fácil. Porque al final, si aquí hace un console.log a y la a aquí le está recibiendo el parámetro de aquí,
o sea, esto es cero y ya está. No hay más. Por más que aquí le pases el uno, este uno se lo está pasando a esta función que se invoca
y él está llegando como b, el uno, es cero. Cero es lo que se logra en la consola. Vale, immediate a se llama con argumento cero
y hace que el parámetro a es cero. Y la b, pues es que la b da igual porque al final el valor de a se captura del scope externo.
Cuestión 3. ¿La función que se autoyama puede acceder al scope externo? Sí, claro, porque aquí justamente esta, esta, quieras o no,
la función aquí es que está dentro de la otra. Es que, claro, si la está creando justamente aquí no hay mucha historia.
Al final una closure te guarda la referencia de las variables que tienes en el scope superior, de forma que puedes acceder a esas variables
desde el mismo ámbito. O sea, en este caso, por eso esto funciona y no es undefined.
En este caso está creando una closure que puedes acceder aquí a este valor de la a.
Pero lo importante es que las closures se están creando cada vez que tú creas una función.
En este caso tú creas esta función y aquí es que se está generando una closure en la que puedes acceder al valor de a
porque cuando se ha creado este ámbito de esta función, justamente puedes acceder a la referencia que está en el scope superior,
que en este caso es la a. Who is who? Vamos a ver qué loguea la consola con el siguiente snippet.
Tenemos la función immediate, que es, de nuevo, es una función que se auto ejecuta.
Se invoca nada más crearse. Entonces dice, si la cuenta es cero, o sea, si count es igual a cero,
entonces count es uno. Esto es muy tricky, ¿vale? Pero creo que es uno y cero por cómo funciona el let.
Esto sería si el count es cero, entonces se crea con let otra variable llamada count con uno y hace un console.log de count.
Por lo tanto, primero se ejecuta esto, count será uno, luego sale de este if y este count que tiene acceso en este scope
es el count que tenemos fuera, será cero. ¿Por qué pasa esto? Porque let, cada vez que tú creas una variable con let,
lo que estás es creando el ámbito que tiene esa variable, es el scope que se genera por las llaves, ¿vale?
Así que este count va a tener el valor uno dentro de este scope. De hecho, se está generando una nueva variable,
aunque tenga el mismo nombre que el de fuera, y al hacer este console.log count va a haber este de aquí.
Y luego, como en este ámbito no existe esta variable, existe la de fuera, pues se va a cero.
Una cosa con las if y, al final una if y, si lo miras fríamente, o sea, la if y, en realidad, no deja de ser esto.
Es exactamente lo mismo. No es exactamente lo mismo, pero me parece.
Lo único que, en lugar de hacerlo así, lo que se está haciendo, una vez que la generas, también la ejecutas.
Piensa, si una vez que tienes claro esto de aquí, pues si piensas aquí, obviamente que tienes acceso a este count de aquí,
porque está en el scope superior y cuando se está creando la closure, pues tienes acceso a ese scope y ya está.
Y aquí estaría pasando exactamente lo mismo. Este count sería el que tienes fuera.
Cuando se crea la closure esta, pues tienes el ámbito de ejecución, este scope queda de afuera y lo tienes accesible.
Sobre el let. Si esto fuese let o fuese const, esto pasaría a lo mismo.
Const o let, o poner uno let y el otro const, esto sería válido y funcionaría exactamente bien.
La tricky closure. ¿Qué es lo que loguea el siguiente snippet?
Creo que es tres veces tres, ¿no?
Es que este es el tema.
Claro, esto lo que va a hacer, aquí habla de la fase uno, claro, la primera vez va a hacer las tres iteraciones directamente.
Va a hacer este timeout.
¿Y qué pasa? Que cuando el timeout termine, las iteraciones del loop ya ha terminado
y el valor que va a haber justamente es que la i siempre será tres porque el loop en realidad ya ha pasado.
De hecho, esto normalmente se puede ver bastante bien, creo, haciendo esto, ¿no?
O sea, si aquí pones, vamos a poner console.log, tú aquí pones la i, la pones fuera del console.log,
sí que ves cómo va pasando al 0, 1, ¿ves? 0, 1, 2 y luego 3.
Luego, lo que sí que puede ser interesante es si le pones let, porque si le pones let, sí que es 0, 1 y 2.
El problema es por el var, ¿no?
Porque el var, lo que estás haciendo es que esa variable, en realidad, sí que no se genere por cada una de las ejecuciones del scope.
Entonces, por eso se queda con el 3.
Pero con el let, habéis visto, pasa a 0, 1 y 2.
Vale, write or ground message.
Vamos a ver el message write or ground.
¿Qué es lo que va a loguear?
Crear el incremento, tiene, vale, create increment.
Tiene un mensaje aquí que lo loguea, incrementar, incrementar, incrementar, loguear.
A ver, esto es una pregunta trampa, ¿no?
Porque aquí uno pensaría que seguro que va a poner aquí que la cuenta es 3, pero tiene pinta de que es 0.
Bueno, si creamos aquí esto del incrementar, el increment hace count más más.
O sea, que se supone que en realidad tendríamos esto.
Pero el log ya tiene el mensaje, claro, la trampa está en que este mensaje ya está creándose, ya está generado.
Este mensaje se ha generado la primera vez.
Entonces, aunque tú incrementes, esto no es un estado mágico que de repente cambia.
Veis aquí esta línea, let message count is count.
Esto se ha ejecutado la primera vez que tú has ejecutado esta función, se ha creado esta variable.
Y luego este console.log message es que este message ya está generado y ya tiene count is 0.
Por más que vayas cambiando el valor este, esta variable ya se ha creado.
Ahora, lo interesante sería arreglarlo.
Si este mensaje, en realidad, en lugar de crearlo aquí, lo creamos cuando se va a ejecutar el log, que es lo que tendría sentido, entonces sí debería ser 3.
¿Por qué? Porque es cuando se ejecuta el log que creas esta variable y entonces sí recupera la cuenta.
Y la cuenta, cuando vaya al scope este, ya se ha modificado con el más más.
Vale, vamos a ver con restore encapsulation.
A ver qué es.
Create stack.
Uy, esta ya se ve más complicada, porque encima va con mutaciones.
Vale, create stack.
Tenemos items, que es un array, tenemos el push, que hace un push, o sea que muta, y el pop, que es el último elemento del array, también lo muta.
Entonces, crea el stack.
Es el stack, que es un objeto que puedes hacer push, puedes hacer push y haces pop.
Y entonces miras, items, encapsulation broken.
Hasta aquí bien.
¿El problema cuál es?
Es que tú puedes modificar este items.
El stack funciona como se esperaba, pero tiene este problema, ¿no?
Que cualquiera puede modificar los items.
O sea, pensaba que iba a tener trampa, pero no veo que tenga mucha trampa.
Sino que el problema es que tú puedes cambiar el valor de items.
Esto rompe la encapsulación, porque solo push y pop deberían ser públicos.
Pero stack.items es público también y te lo puedes cargar.
Y no debería ser accesible.
Se factoriza lo siguiente para que no se...
Bueno, pero esto no tiene mucha historia.
Si es tan fácil como solucionar la encapsulación, esto sería tan fácil como esto, ¿no?
Con esto no podríamos hacer esto.
Así que hacemos así.
Stack.items y ya está.
Y esto será undefined, pero yo creo que es esto.
Puedes leer push de undefined.
Ah, bueno, porque...
Vale, porque...
Vale, vale.
Aquí es donde está el truco, entonces.
El truco está en el disk.
Porque el disk, justamente como es un objeto, el disk se refiere al objeto.
Por eso cuando tenía esto, tenías que poner el disk.
Esto además, tú cuando creas un stack en este caso, te lo puedes simplificar.
Súper fácil, ¿verdad?
O sea, es más fácil entender esto que no tener que poner un disk, ponerlo aquí en el items.
Al final lo ideal sería hacer esto.
Poner un getItems y que esto devuelva items.
De forma que tú hagas un stack.getItems.
Ya veréis.
Vamos a hacer esto.
Y esto es lo que tiene todo el sentido del mundo.
Tener un getter así, de esta forma.
Yo creo que esto sería lo ideal.
A ver, vamos a guardar aquí.
Hacemos esto.
Vale, ¿veis?
El 5 era lo del pop.
El items es undefined.
Y luego hago un getItems y me da el items.
Pero no puedo cambiar desde fuera.
No puedo cambiar los items.
Ya no lo...
Esto es un patrón realmente de programación.
Así que esto está bien controlarlo.
De esta forma, lo que estás haciendo es que items sea como una propiedad privada de este stack.
¿Vale?
Así que, bueno.
Tengo una forma de hacer propiedades privadas de un objeto.
Porque al final ese scope es totalmente privado y no hay forma de que tú accedas y lo cambies.
Vale.
Cuestión 7.
Escribe una función multiply que multiplique dos números.
Si multiply se invoca con dos argumentos, tiene que volver la multiplicación de dos argumentos.
Pero si se invoca con un argumento, entonces debería devolver otra función.
Cuando se llame, entonces hace la multiplicación.
Dice, si num2, type of num2, es undefined.
Entonces tiene que devolver otra multiplicación.
Multiply, entonces double.
Ah, vale.
Y si no, pues num1 por num2.
Y entonces, si no, esto devuelve una función que lo que hace es devolver esto.
Pues entiendo que esto debería ser así.
A ver, que esto al final, además, lo podríamos reescribir así.
Un poquito mejor, ¿no?
Si type of num2 es undefined, entonces devolvemos num1 por num1 y si no, es num1 por num2.
Así que ahora abrimos aquí la consola y hacemos multiply dos con dos, cuatro.
Y si solo pongo el dos, esto me devuelve una función que si la llamo, vale, ya está.
La arrow tiene que tener parámetro.
A ver, tiene que tener parámetro la arrow.
¿Qué parámetro?
Pues sí, ya lo hemos puesto, ¿no?
Esto, en realidad, no tiene que tener parámetro, ¿no?
Ah, sí.
Sí, tienes razón.
Perdón.
Como he leído este double, yo pensaba que era doblarlo y ya está.
Es básicamente multiplicar por el primero.
O sea, que devolviese una función a la que le puedes pasar otro número para que multiplique.
Que si tenemos double, esto sería esto, ¿no?
Y ahora podrías doblar el 5, exacto.
Podrías poner triple, y esto sea multiply 3, ¿no?
Y triple por 5, 15.
Puedes acceder a este parámetro que le está llegando por aquí.
O sea, que porque tienes acceso a ese parámetro inicial.
Está bastante interesante.
Muy bien.
Me gusta.