Transcripciones
1. Introducción: Estamos en una nueva sección
y temas emocionantes. En esta sección
trataremos algunos temas que son realmente
centrales para JavaScript. Todos estos temas
se centran las funciones y la
naturaleza de las funciones. Estos conceptos han llevado a
muchos de los patrones que han definido un alto nivel de experiencia en
desarrollo. Y es importante que
entiendas y seas capaz aplicar lo que hay en esta
sección en tu propia codificación. Primero hablaremos sobre la naturaleza de las funciones
en JavaScript. La función JavaScript es muy poderosa porque es
un ciudadano de primera clase. Y las funciones se pueden utilizar
en formas de orden superior. Vamos a ver el cierre, una característica que creo que es una de las características más útiles y
potentes del lenguaje JavaScript. Nos ocuparemos de invocar
inmediatamente las funciones y el
patrón alrededor de eso. Entonces tenemos mucho que cubrir. Así que comencemos.
2. Las funciones son ciudadanos de primera clase: Anteriormente en este curso, hablé de cómo
están los objetos en todas partes en JavaScript, excepción
de los primitivos, todo lo demás es un objeto. Entonces, como discutimos en ese
momento, las funciones son objetos. El hecho de que las funciones sean objetos es una característica tan
importante. Conlleva a que las funciones sean ciudadanos
de primera clase
en JavaScript. Ahora bien, la idea de que las funciones
son de primera clase simplemente significa que las funciones son tratadas como valores que
se pueden pasar por ahí. Y como las funciones son objetos, eso es lo que
lo hace posible. Entonces, cuando pensamos en un valor, normalmente
pensamos en algo así
como una cadena o un número. Mientras que en cualquier lugar se puede usar un valor como una cadena o un
número. Una función puede ser utilizada también porque son
tratados como valores, lo que los hace de primera clase. Para cimentar esta idea, veamos varios ejemplos donde se pueden
usar valores tradicionales y mostrar que una función se puede usar
en un mismo lugar. Ahora los dos primeros ejemplos
son bastante obvios. Podemos asignar un valor como
un número a una variable. Bueno, también podemos asignar una función
a una variable. Y lo hemos hecho muchas
veces ya en cualquier momento
creamos una expresión de función
como se muestra aquí. Estamos asignando esa
función a una variable. Eso es bastante común. Eso no es extraño
para nosotros en este momento. Ahora antes de mostrar
este segundo ejemplo, que también es
bastante obvio, quiero mostrar algo sobre las funciones aquí y cómo se
asignan a la variable. Nos divertimos diez. Ahora, ¿y si tuviera
que hacer algo así? ¿Y si creé
otra variable? Y es divertido diez a y fijó
eso igual para financiar diez. Entonces, ¿qué está pasando aquí? Mientras que, como las funciones son
objetos, lo que está haciendo, está asignando una referencia a esta misma función aquí mismo. Asignar otra
referencia para financiar a. No es invocar
la función y colocar un diez en Fontan. Recuerda que esa es una diferencia
clara. Tenemos que usar paréntesis
para invocar una función. Así que vamos a ver
esto muy rápido. Si tuviéramos que ver la diversión
diez a en la consola, déjame abrirla. Vemos que es una función. Eso es lo que nos están
mostrando aquí como una función. No obstante, si tuviéramos que invocar a Fontan a poniendo
impresiones después de él, entonces obtenemos los diez devueltos, que es lo que se supone que debe hacer esa función
. Punto tan importante sobre el
uso de la variable a la que se le asigna una
función. Si no ponemos
paréntesis después de
él, no va a invocar
esa función. Bien, ahora, el segundo ejemplo
que queremos mirar, solo
voy a
desplazarlo aquí arriba es una función que se puede asignar
a una propiedad de un objeto. Ahora ya lo hemos visto
muchas veces. Entonces por eso esta también es
obvia. Básicamente const OBJ y establece eso igual a un
objeto como este. Y luego si nos
divertimos dos puntos y entonces aquí es donde pondríamos la función que
se le asigna a eso. Y éste sólo
va a registrar diversión. Ahora, recuerda invocar esto, usamos la sintaxis de punto. Simplemente hacemos OBJ dot y luego cualquier propiedad a la que se le asigne en este caso, diversión. Una vez más, utilizamos las impresiones
dobles para invocarlo. ¿Bien? Ahora bien, esto, como hemos visto antes, se
puede hacer con un método de
atajo como ese. Eso
lograría lo mismo, estableciendo ahí una función. Y nos divertimos log
a la consola. Voy a cerrar esto solo
un poco para que podamos configurar la consola. Bien, entonces ese es
el segundo. Esos eran
demasiado obvios. Entonces el tercero, tal vez no del todo tan obvio. Y esta es una función que se
puede almacenar en una matriz. Así que vamos a configurar una matriz aquí. Y ahí vamos a poner
un número. Un valor puede entrar en array, ya lo sabemos, pero ¿podemos poner una función
ahí también? Bueno, sí, podemos.
Y esta vez voy a hacer una función de flecha. Básicamente sólo
va a devolver diez, como lo hemos hecho en el pasado. Así que ahora tenemos una función en la segunda posición
de esta matriz. Y podemos invocar eso
utilizando de nuevo las tendencias. Entonces tenemos que
indicar la posición en la matriz así. Y luego solo ponemos amigos
después de eso, lo vamos a invocar. Entonces esto debería devolver diez. Entonces, si logramos eso
en la consola, así, deberíamos
conseguir diez en la consola. Y ahí vamos.
Comenté este de aquí arriba, así que atiende lo único
que estamos viendo allá arriba. Por lo tanto, un valor se puede almacenar en una matriz y una función se
puede almacenar en una matriz. Ahora, una función puede ser parte de una expresión tal
como lo es un valor. Echemos un vistazo a éste. Voy a hacer un sencillo registro de
consola dentro de ahí. Voy a poner una
expresión para que
podamos ver los resultados
de esa expresión. Aquí está la expresión. Yo sólo voy a
hacer 30 más ¿qué? Bueno, vamos
a hacer una función. Entonces voy a declarar
una función aquí. Y voy a hacer
que vuelva diez. Ahora. En este momento esto
no va a sumar 30 más diez porque no se invoca esta
función. Lo acabamos de declarar aquí. Entonces, si tuviéramos que guardar esto, permítanme comentar que
si tuviéramos que guardar
esto, simplemente concatena el texto de esa función
al número 30. No obstante, si fuéramos a
invocarlo y esto lo está invocando de
inmediato. Y este es un tema que
vamos a discutir en esta sección con
más detalle más adelante. Pero si pongo
impresiones dobles justo después de eso, ahora veamos qué pasa. Ahora. Invoca a la función, devuelve un bronceado y
luego agrega 30 a diez. Y así ponemos una función como
parte de una expresión, igual que podríamos
cualquier otro valor. Ahora bien, para hacer lo mismo, solo para que estés consciente de hacer lo mismo con
una función de flecha, necesitarías hacer
algo como esto, 30 más. Y luego aquí está nuestra función de
flecha. Y si definimos esa
flecha gorda ahí de devolver diez, eso es genial, excepto que no podemos
poner marcas inmediatamente después de eso. Tenemos que encerrar
todo entre paréntesis, así. Entonces podemos poner
paréntesis después de él. Ahora deberíamos llegar a las sentencias
log de consola a
40. Y ahí vamos. Entonces así es como
lo harías con una función de flecha. Ahora, el siguiente ejemplo, podemos pasar valores
a una función. Un número se puede pasar
a una función de cadena, se
puede pasar en la función. Bueno, ¿entonces las funciones se pueden
pasar a funciones? Así que piensa en las devoluciones de llamada. Hemos hecho mucho con las devoluciones de llamada. Y ese es un ejemplo
de donde estamos pasando una función
a otra función. Entonces, el ejemplo más común que probablemente
hemos hecho en este
curso es usar setTimeout. Entonces setTimeout tiene
dos parámetros. Una es una función que
pasamos y la otra es la cantidad de tiempo
en milisegundos. Entonces eso sería 1 s ahí. Este primer parámetro es
solo una función que pasamos. Y ahí puedo hacer una
función de flecha para ésta. Y sólo vamos a consola dot log. Se acabó el tiempo, algo así. Entonces aquí estamos pasando una
función a otra función. Entonces si decimos esto, obtenemos el 240 es
un segundo después
obtenemos el tiempo se
muestra arriba en la consola. Ahora, el último ejemplo
que queremos ver es que una función puede ser
devuelta de una función. Así que aquí abajo en la parte inferior. Así que al igual que podemos pasar una
función a una función, podemos devolver una también. Así que déjame armar
algo, divertirme. Establezca eso igual. Aquí estamos declarando una función. ¿Y qué vamos a regresar? Lo que vamos a
devolver una función. Voy a declarar esto aquí después de la declaración return, y solo tendremos
un registro de consola. ver, me devolvieron. ¿Cómo hacer eso? Entonces esa es nuestra declaración de devolución. ¿Y qué estamos regresando? Bueno, podríamos devolver un número, podemos devolver una cadena, podemos devolver una función porque se
trata como un valor. Entonces ahora con esta configuración, si vamos a const nuevo fondo, vamos a almacenar aquí
la función que se devuelve
y establecemos esa igual para divertirnos y usar al
príncipe para invocarla. Adelante y guarda eso. Aquí están nuestros
registros de consola que tenemos ahí arriba. Pero ahora veamos qué
nuevo fondo contiene. Ahora si pongo nueva diversión
aquí sin las marcas, verá el texto
de esa función. Pero si hago nueva diversión con
las marcas y lo hago invocar, entonces obtenemos el valor de retorno. Tenemos la instrucción de
registro de la consola, no el valor de retorno. Entonces ahí volvemos
una función. Ahora algo que podemos hacer aquí. He asignado la
función return a una variable, pero también podría simplemente
llamar, divertirme así. Y eso va a
devolver una función. Bueno, ¿y si
quisiéramos invocar esa función
que se devuelve? Simplemente podemos ingresar otro
conjunto de planes justo después de él. Así que estas primeras impresiones actúan
sobre la función get fun. El siguiente conjunto de marcas actúan sobre esta función que se devuelve y hacen que esa
función sea invocada. Entonces ahora, si seguimos
adelante y guardamos esto, deberíamos ver que me
devolvieron en la consola. Y ahí está nuestro
ojo fue devuelto. Ahí está nuestra instrucción de registro de la
consola SetTimeout. Así que hay un total de seis ejemplos de cómo
podemos usar una función, igual que
usaríamos cualquier otro valor, como un número o una cadena, porque una función en
JavaScript se trata como un valor y
por eso es de primera clase. Por eso llamamos a las funciones
en JavaScript de primera clase. Bien, ahora estos
dos últimos ejemplos que vimos, vamos a
profundizar en más detalle en el siguiente tema cuando
hablemos de funciones de orden superior.
3. Funciones de orden superior: En el tema anterior, mostramos cómo las funciones en
JavaScript son tratadas como primera clase porque son
tratadas como otros valores. En este tema, vamos
a ampliar esa idea medida que hablamos de funciones de
orden superior. Las funciones de orden superior son simplemente funciones que actúan sobre otras funciones ya sea tomándolas como argumento o
devolviendo una función. Vimos ejemplos de eso
en el tema anterior. De hecho, los dos últimos ejemplos mostraron funciones de orden superior. El hecho de que JavaScript
admita funciones de primera clase permite crear funciones
de orden superior. Entonces el concepto de
funciones de primera clase explica cómo se tratan
las funciones en
JavaScript como valores. El concepto de funciones de
orden superior explica cómo las utilizamos. Ahora aquí están esos dos
últimos ejemplos que usamos en el tema anterior. Tenemos un tiempo de espera establecido y estamos pasando
una función aquí. Y también tenemos
otro parámetro que es la cantidad de tiempo. Entonces el hecho de que podamos usar una función como
parámetro y pasarla hace que esta función actúe sobre la función setTimeout
actuando sobre otras funciones. Este es el que ha pasado
y sobre el que está actuando. Y así por eso, es una función de orden superior. Aquí abajo. Esto
consigue una función divertida. Esta devuelve una función y debido a que está actuando
sobre otras funciones, es una función de orden superior. Entonces, básicamente,
las funciones de orden superior o bien toman funciones como un parámetro
o las devuelven. Entonces entendemos qué son las funciones de
orden superior, pero ¿por qué son tan importantes? Ahora la
aplicación más común de funciones de
orden superior en
JavaScript es la devolución de llamada. Existen varios métodos en JavaScript que nos permiten pasar una función que será utilizada como parte de ese método o función. Entonces se le devolverá la llamada. Cada vez que creamos
un oyente de eventos, estamos configurando una devolución de llamada. Y así son bastante
comunes en JavaScript. Ahora quiero usar la
función setTimeout como ejemplo y diseccionar por qué es mejor como función
de orden superior, ¿qué la hace mejor? Así que voy a ir a un archivo de
código diferente ahora donde tengo dos funciones setTimeout
ya creadas. Ahora primero, quiero centrarme
en el último parámetro, que es la cantidad de milisegundos que ejecuta
el setTimeout. Así que ahí estamos pasando datos. Al pasar datos a
esta función setTimeout, hace más flexible. En lugar de llamar a una función
setTimeout que siempre se ejecuta durante 3 s, podemos pasar el número de milisegundos que
queremos que se ejecute. Y correrá por ese número. Entonces,
al poder pasar datos, hace
que la función sea
más flexible. También nos ayuda a evitar que
repitamos código. Si tuviéramos que tener una función
setTimeout que se ejecutara durante 3 s y
una que funcionara durante 4 s. Básicamente
están haciendo cosas
muy similares, solo una cantidad de tiempo diferente. Y así al poder pasar datos como lo
hemos hecho aquí, nos aferramos a ese principal seco. No te repitas. No repitas código. Eso lo hacemos pasando
en un parámetro. Bueno, lo mismo puede
decirse de pasar en una función, por hacer una función de
orden superior. Los datos que pasamos
controlan su flexibilidad. Por qué datos puede actuar. La función que
pasamos controla su flexibilidad al afectar
el aspecto funcional de la misma. Entonces tomemos estos
dos ejemplos. Tengo un setTimeout que después un segundo es simplemente
iniciar sesión en el registro de la consola. Ese es un ejemplo. Tengo un setTimeout
aquí abajo que después de 2 s, registra o devuelve
dos más dos. Ese es otro ejemplo. Ahora bien, es posible que para
cumplir con ambos requisitos
funcionales, podríamos haber creado una
función de registro SetTimeout que cada vez que se llamaba log
algo a la consola, acabamos de pasar en los
datos que queríamos log. Y podemos crear una función setTimeout add que cada
vez que se llamara, agregaría algunos números
después de que expirara el tiempo. Eso serían dos funciones
separadas. Y estaríamos repitiendo código. Pero debido a que setTimeout
es de orden superior, podemos pasar en una función
que puede hacer cualquier cosa. Entonces es más flexible. Algunos pueden argumentar
que es más complejo. Y creo que es cuando
lo aprendes por primera vez, cuando aprendiste por primera vez sobre las funciones de
orden superior y entendiste
cómo usarlas. Pero una vez que estás
familiarizado con ellos, realmente no
es
mucho más difícil. Realmente no lo es. Y la flexibilidad
se vuelve muy poderosa. Entonces todo ese concepto de seco, no te repitas, es una de las razones por las que queremos tener funciones de orden superior. Ahora, como mencioné,
JavaScript está lleno de funciones de orden superior. Los métodos en muchos de los diferentes tipos son funciones
de orden superior. Por ejemplo, las matrices tienen varios
métodos que son de orden superior. Aceptan una función
como parámetro y luego hace algo usando la función
que se pasa. Pero solo quiero
señalar y hacerte consciente que las funciones de orden superior se encuentran por todas partes en JavaScript. Creo que algunas personas que son nuevas JavaScript o que apenas
empiezan en JavaScript, las evitan porque
parecen complejas, pero no puedes evitarlas. Son tan poderosos. Bien, pasemos
al siguiente tema.
4. Crear tu propia función de orden más alta: Hay muchos métodos
en JavaScript que
aprovechan las funciones de
orden superior. Resuelven problemas utilizando patrones que aprovechan esas funciones de orden superior. Y podemos aprender de esto
y usarlo en nuestro propio color. Como solo un ejemplo, veamos este método de ordenación que está disponible para matrices. Aquí tengo dos matrices, una con nombres y
otra con números, y las vamos a ordenar. Entonces hagamos los nombres y
también números como este. Entonces echa un vistazo a los resultados. Entonces, si guardamos eso, déjame volver a salir de aquí
a la consola. Y ahora nos fijamos en esos
dos arrays, nombres y nums. Podemos ver que con los nombres, las cosas se ordenan correctamente. Están ordenados por orden
alfabético. Pero lo que
hace el método sort con los números es que los
convierte en
una cadena y luego ordena alfabéticamente en
función de la cadena. Y así estamos consiguiendo
algunas cosas muy raras aquí con números. Y así ordenar por sí mismo
no es ideal para los números. Sin embargo, el método sort se
configuró para tomar una función de
orden superior, una función de comparación
como parámetro. Podemos pasar una función
al método sort. Utilizará esa función para
hacer una comparación de elementos. Tomará cada elemento
dos a la vez hacia abajo a través la matriz y
los comparará en función de la
función que pasamos. Y entonces eso
determinará el orden de ordenación. Ahora bien, la forma en que funciona es si el primer argumento
que se pasa. Entonces cuando creamos nuestra función, pasa en los dos
primeros elementos. Si el primer argumento debe aparecer antes del
segundo argumento, entonces necesitamos
asegurarnos de que nuestra función devuelva un número menor que cero. Si el segundo argumento
debe venir antes del primer argumento que un número mayor que cero,
debe ser devuelto. Ahora, piensa en la
ventaja de eso. Vamos a hacer esto
en un minuto. Pero piense en
la ventaja de que este método de clasificación
ya no se limita a ordenar cadenas. Ahora podemos hacer que
ordene otras cosas porque acepta una función
como uno de sus parámetros. Y usa esa función
y la llama para, en este caso, los elementos dos a la vez a
medida que los pasa adentro. Entonces probemos eso con nums. Entonces voy a
pasar en una función. Y como dije, esa función necesita
aceptar dos parámetros. Va a aceptar
los dos primeros elementos,
y así sucesivamente, ya que funciona
a través de esa matriz. Ahora, ya que necesitamos devolver
un número menor que cero, si el primer argumento
debe llegar a ser, debería venir antes
del segundo argumento, podemos hacer algo como esto, devolvió a menos b. Y esto hará un orden de ordenación. menor a mayor. Semana podría revertir eso
yendo en la otra dirección. Porque mira, si se pasa
100 y se pasa
95 para a y B, 100-95 equivale a cinco. Entonces ese es un número que
es mayor que cero. Y eso significa que el segundo argumento vendrá
antes del primer argumento, por lo que pondrá 95 antes de 100. Ahora, va a comparar
todos esos números juntos y ponerlos en orden
ordenado,
sabe cómo hacerlo. Todo lo que tenemos que hacer es pasar la función como
lo que hemos hecho aquí. Entonces, si guardamos eso y volvemos a
echar un vistazo a nums, vemos que es de
menor a mayor. Así que numerosos métodos en JavaScript
aprovechan esto. La capacidad de aceptar una función
y llamarla cuando sea necesario. Y podemos hacer
lo mismo en nuestro código. Podemos
aprovecharlo también. Digamos que quería crear una función que
procesara cadenas. Déjame seguir adelante
y copiarlo aquí y luego lo haremos, ya
hablaremos de ello. Aquí está mi función que
procesa cadenas. Permitimos que se
pase una cadena, y luego convertimos esa convierte automáticamente
esa mayúscula. Eso es lo que hacemos en esta función de cadena de
proceso. Estoy tratando de mantenerlo
simple para que podamos mantener esta
información de devolución de llamada, el foco. Entonces
lo convertirá a mayúsculas. Sin embargo, si enviamos una
devolución de llamada, hará más. Hará lo que
indiquemos con una función. Entonces de pronto esta función
es mucho más poderosa. Puede hacer mucho más. Ahora fíjate cómo tratamos
con la devolución de llamada. Creamos una nueva cadena
con dos mayúsculas. Pero luego comprobamos para ver si el tipo de devolución de llamada
es igual a la función. Entonces si algo ha sido pasado
y es una función, entonces seguimos adelante y lo invocamos. Y pasar en esta nueva cadena que ya hemos hecho,
la conversión en mayúsculas. Esa devolución de llamada hace
lo que sea necesario y la devuelve. Y luego devolvemos ese valor. Si no hay devolución de llamada, simplemente devolvemos la nueva
cadena que creamos. Entonces esto te puede dar una idea, un patrón para hacer funciones que son
mucho más flexibles, mucho más poderosas. Ahora sigamos adelante
y solo probemos esto. Solo usémoslo para que
podamos ver cómo funciona. Bien, voy a
hacer un registro de consola. Así que quiero registrar los
resultados de lo que se devuelve de la cadena procesada o de la cadena procesada
a la consola. Entonces llamo process stream, esa función ahí mismo. Y voy a
pasar en una cuerda. Así que sigamos adelante y
pongamos una cuerda aquí arriba. Const STR uno. Voy a poner esto igual a. Esto es una cuerda, algo sencillo así. Así que queremos pasar eso en STR uno a esta función de
flujo de proceso. Ahora queremos pasar
en una devolución de llamada. Y voy a configurar
esa devolución de llamada aquí mismo. Entonces entro función, va a ser función
anónima. Hay una ortesis rizada ahora
puedo definir lo que hace. Pero una cosa que tenemos que
hacer es
asegurarnos poner una variable aquí para el parámetro que solo
voy a
llamar a esa vocal por valor. Porque mira lo que está
pasando aquí arriba. Está pasando esa nueva transmisión a estas funciones de devolución de llamada. Entonces tenemos que
asegurarnos de aceptarlo, aceptarlo, y luego
hacer algo con él. Bueno, digamos que todo lo que
queremos hacer más ya que solo crear una matriz
a partir de esa cadena se dividirá en el espacio. Entonces usamos el método split
y split en el espacio. Entonces volveremos eso
una vez que hayamos hecho eso. Entonces aquí está el método split. Y luego solo ponemos espacio ahí como lo
que queremos dividir. Entonces, ¿qué debemos obtener, lo que debería
iniciar sesión en la consola es esta cadena todo en mayúsculas? Dentro de una matriz en cada
palabra estará en su, será su propio elemento en la matriz. Y así, hemos hecho que nuestra función de flujo de
procesos sea más potente y flexible
al hacerla de orden superior. Entonces sigamos adelante y guardemos
esto y echemos un vistazo. Y ahí obtenemos una matriz. Todo en
mayúsculas, cada palabra, su propio elemento en la matriz. Entonces, lo que quiero
que saques de esto es el poder de las funciones de
orden superior. Las funciones de orden superior se
utilizan en todo JavaScript. También podemos aprovechar esa característica en nuestro propio código. Y con este sencillo ejemplo, eso es lo que hemos hecho. Bien, pasemos
a la siguiente sección.
5. Comienzo de ejercicio: creación de una función de orden: A lo largo del curso, ya
hemos visto muchos
ejemplos de funciones de orden superior cuando
hablamos del patrón de
devolución de llamada. Como dije, esas son todas funciones
de orden superior. Acabamos de ver
algunos otros ejemplos en los últimos temas. Entonces creo que ya es el momento de dar un ejercicio donde tengo que crear una función de
orden superior. Creo que una vez que creas
uno por tu cuenta, ayuda a cimentar el poder
de toda esa idea, que creo que es
importante cimentar, es algo para recordar
sobre JavaScript. Esa lente a JavaScript, una de las, una de las características que lo
hace tan potente. Esto es lo que me gustaría que hicieras. Tengo una variable
declarada su saludo, y luego estoy llamando a una función. Y fíjate que estoy pasando
en tres parámetros. Uno es un saludo, porque esta función es crear saludo va a
crear acordando para nosotros, otra como nombre. Y entonces el tercero
es una función. Entonces, lo que me
gustaría que hicieras es construir la función create greeting y que tome
tres parámetros. Si solo se proporcionan dos parámetros, simplemente devuelve un saludo. Pero si se proporciona un tercer
parámetro, que es la función
antes de
que devuelva ese saludo juntando el
término y el nombre, debería tener esa función
actuar sobre ese saludo. Por lo que primero
debe
juntar estas dos piezas y luego verificar para ver si la función existe
y tener un acto sobre ella. Y así crear saludo va a ser una función
de orden superior. Nos va a dar un
poco más de flexibilidad. No sólo podemos
pasar datos y que se vuelvan saludos
compilados, también
vamos
a poder pasar en una función que nos
hará hacer
cosas diferentes con ese saludo. Ahora bien este es un ejemplo sencillo, pero muestra el patrón de una función de orden superior
o el patrón de usar una devolución de llamada para hacer que la función que creas sea
más flexible para darle adicional funcionalidad para que no
te estés repitiendo. Bien, adelante
y pruébalo. Y luego, cuando
estés listo, pasa
al siguiente tema y lo
pasaremos juntos.
6. Final de ejercicio: creación de una función de orden: Bien. ¿Cómo te fue con eso? Voy a seguir adelante
y hacerlo aquí. Eso te da la
oportunidad de comparar lo que he hecho con
lo que tú has hecho. Tal vez aprenda algunas cosas
adicionales también. Entonces arriba, voy a
seguir adelante y configurar Función,
crear, saludar.
Así como así. Ahora queremos tres parámetros. Voy a
llamarlos a su vez griegos y luego fn para la función
que se podría pasar. Bien. Ahora, voy
a declarar variable, y este va a ser
el saludo inicial, solo armando esos dos, el término y el nombre. Y parece que no lo
hice no
sé por qué pongo saludar ahí
en vez de nombre. Ahí vamos. Entonces va a poner término
y nombre juntos. Y va a colocar
eso en esta variable. Voy a usar una cadena
de plantilla. Entonces utilizo una garrapata posterior, y luego uso el signo de dólar y las
llaves para una variable. La primera variable
quiero incluir su término y después quiero
un espacio entre ellos. Entonces voy a incluir
la siguiente variable, que es nombre así. Y así hemos creado nuestro saludo y eso
podría ser devuelto. Si no hay función, entonces seguiríamos
adelante y la devolveríamos. Entonces la forma en que voy a hacer esto es voy a verificar si este valor que se pasa
es igual a una función. Si es así, seguiremos adelante y ejecutaremos la función en él
y devolveremos resultados. De lo contrario, solo
tendré una declaración de devolución después de la declaración if. Si la sentencia if no se ejecuta entonces la sentencia return se ejecutará y devolverá
este saludo. Entonces veamos cómo lo hacemos. Voy a justo si entonces tipo de Así es como
averiguamos si algo es un tipo de función de Fn triple igual y luego
dentro de la función de comillas. Entonces, si eso es una función, esta parte del código
es bastante simple. Simplemente queremos devolver la
invocación de esa función. Pero cuando lo
invocamos, queremos pasar en saludo. Ahora veamos cómo funciona eso. Entonces una función se pasa y se coloca
en esa variable. Ya que podemos tratar
las funciones como valores, desde la primera clase, podemos
almacenarlas en una variable. Y así ahora que esa función está
contenida esa variable, entonces
podemos invocarla usando paréntesis y pasamos en
un parámetro aquí mismo. También podemos verificar para ver
si es una función
usando el tipo de y eso debería ser un punto y coma
ahí. Entonces déjame arreglarlo. Dice parte realmente
no es tan difícil. A veces la
parte más difícil es lo que pasas, la funcionalidad que pasas en la
forma en que quieres
lograr algo. Bien, sigamos
adelante y terminemos con esto. Entonces si esto no se ejecuta, si esta parte aquí no se ejecuta, todavía
queremos
devolver un saludo. Y así en la siguiente línea, sólo
voy a poner
regreso, saludo. Y de esa manera puedo usar esto con una función o
sin una función. Lo hace
aún más flexible para mí. Bien, así que sigamos
adelante y guardemos eso. Y saltemos
aquí y Sue está consiguiendo abrir la consola aquí. Y declaré una variable
de saludo. Veamos qué hay en eso ahora. Aviso que tenemos
buenos días Anika. Entonces ese era el término en
nombre de esto pasado en. Y entonces estos
exclamaciones fueron lo que se agregó en
base a la función. Yo los paso, déjame
saltar de nuevo a esa llamada. Entonces término, nombre y hay una función
va a tomar el saludo
y luego va, Aquí está la
cadena de plantilla otra vez. Entonces va a tomar lo que ha terminado porque ese saludo
se pasa aquí mismo, se pasa a él, tan rico, lo recibe en esta variable. Y luego usamos esa variable en una cadena de plantilla con signo de
exclamación después de ella. Bien, así que eso está
funcionando para nosotros. Ahora, permítanme simplemente hacer un ejemplo de crear gradación sin
pasar en una función. Me voy a ir. Ahora
sólo voy a usar mi nombre aquí. Y sigue funcionando porque
hicimos ese tipo de chequeo. Lo hacemos si sentencia
sigue funcionando si no
pasamos en una función. Ahora, sólo para mostrar
la flexibilidad de esta sencilla
función de orden superior, permítanme hacer otra. Aquí voy a hacer una función
diferente. Puedo escribir correctamente aquí. Y ahora para esta función
en particular, una vez más, necesitamos una variable para aceptar un saludo
que se le pase. Haciendo una función de flecha otra vez, y solo voy a
convertirla a mayúsculas. Entonces algo sencillo como eso. Entonces aquí hay otro ejemplo. Ahora si presiono return, ahí
consigo esa sintaxis. ¿Puedes ver y?
Fíjate que me perdí la coma ahí mismo. Así que voy a volver a subir y sólo
voy a volver por aquí. Entonces el mensaje está
mal formado, función flecha. El motivo está mal formado es porque no teníamos
una coma separándose. Entonces, una vez que llegó a
ello, estaba considerando esto
también como parte de él. Y así considera
que las formas metálicas. Entonces ahora si presiono Retorno y lo
obtenemos todo en mayúsculas, solo muestra un ejemplo
de lo que podemos hacer con esto ahora, función muy
flexible. Bien, ojalá, ese
fue un buen ejercicio para ti al aplicar toda la idea
de funciones de orden superior. Bien, sigamos adelante.
7. Cierres: Hemos llegado a lo que
creo que es uno de los
conceptos más importantes en JavaScript. Cierre. Necesitas entender y usar closure para ser un desarrollador serio de
JavaScript. Ahora el cierre es
algo que no es entendido por los nuevos desarrolladores de
JavaScript. Puedo recordar cuando por primera vez tuve la idea o entendí
la idea de cierre. Fue un momento ajá para mí. Y luego pude
verlo en mucho código y usarlo para resolver problemas
particulares. Entonces primero quiero
mirar una definición. Esto viene de Kyle Simpson. Afirma que el cierre es
cuando una función es capaz de recordar un
acceso a su alcance léxico, incluso cuando esa
función se está ejecutando fuera de su alcance léxico. Las variables y funciones de su ámbito léxico siguen siendo
accesibles a una función, aunque ese alcance léxico no
sea el entorno actualmente en
ejecución. Ahora esas variables
y funciones se mantienen en la memoria porque el motor JavaScript ve que todavía hay algo
que pueda referenciarlas. Ahora bien, ¿cuándo sucede este
tipo de cosas? ¿Cuándo se ejecuta una función
fuera de su alcance léxico? Bueno, es realmente
bastante frecuente, pero para saber eso y
para explicarlo mejor, tenemos que empezar a
mirar algunos ejemplos. El primer ejemplo
que quiero mirar,
voy a llamar a esta
función de saludo retardado. Y vamos
a ver cómo funciona esto. Y luego voy
a explicar qué está pasando y qué
cierre está ocurriendo. Entonces tenemos una función
aquí que somos capaces de pasar en un nombre de
parámetro. Esto nos va a hacer
un saludo. Vamos a declarar dos variables dentro
de esta función. Uno es el saludo. Buenos días, después de eso haremos
un espacio. Y entonces voy a usar uno saltado para declarar ambos de estos. La otra es una
variable bombeada para puntuación. Y sólo vamos a poner eso un signo de
exclamación. Eso es todo. Entonces ahí están nuestras dos variables. Ahora, todo lo que vamos a
agregar es un setTimeout. Hemos usado
mucho esto en el pasado, así que esta será una excelente
manera de ilustrar el cierre. Settimeout es tener una
función pasada en él. Como sabemos, esa
función no invocará hasta después de que haya expirado el tiempo. Y cuando haya expirado el tiempo, si recuerdas, la función
se coloca en la cola. Y entonces una vez que ningún otro
JavaScript se
está ejecutando, luego se agrega a la
pila y se ejecuta. Ahora bien, esto es lo que
vamos a registrar. Sólo vamos a registrar
la variable griega más el nombre que se
pasa en m más. Bien, ahora sigamos
adelante y pongamos esto a 5 s. así. Bien, ahora déjame hablar de
esto en términos de cierre antes de que realmente lo veamos. Y déjame seguir adelante y hacer grado retrasado viendo
aquí abajo así que lo invocará. Pero en términos de cierre, entonces cargamos este
archivo JavaScript y la función. Y a medida que comenzamos a
ejecutar el código, nos encontramos con esto, le
agregamos una función. Y luego nos encontramos con
esto que invoca. Esa función se
coloca entonces en la pila y comienza a trabajar a través
del código dentro de ella, crea un contexto de ejecución, contexto para este código. Y así esta variable y esta variable
y esta variable son todas accesibles por el
código dentro de la función. Bueno, encuentra
un tiempo de espera establecido y setTimeout es manejado
por el navegador como sabemos. Y así el navegador empieza a
contar los 5 s. bueno, esa función
completa su hecho. Antes de que termine esta cuenta
regresiva. Se hace y se
retira de la pila. Entonces, ¿qué pasa con
estas variables? ¿Siguen siendo accesibles
por esta función? Debido a que esa función
ni siquiera es agregarla
a la cola todavía, seguimos
contando los 5 s. Luego se agrega a la cola. Y luego cuando hay espacio, se agrega a la pila. Y luego comienza a ejecutar
el código dentro de él. Entonces aquí está el código dentro de él. Y ahora tiene que agarrar saludo, nombre y punk, pero esta función ya está
eliminada de la pila. Entonces, ¿qué pasa? Bueno, aquí es donde
entra el
cierre porque el
motor JavaScript sabe que esta función todavía
tiene una referencia a estas variables que forman
parte de su alcance léxico. Léxica donde se escribe. Y este es el alcance aquí. Por lo que todavía tiene acceso a eso. Estos se conservan en la memoria. A pesar de que esta función ha terminado de ejecutarse y se
elimina de la pila, estas variables no se
limpian su alcanzada en la memoria. Entonces esta función
es capaz de acceder a ellos porque formaban parte
de su alcance léxico. El motor Javascript sabe lo suficiente como para mantenerlos cerca para
poder usarlos. Entonces eso es cierre. El cierre se crea alrededor esas variables para que esta función más adelante
pueda acceder a ellas. Una característica muy potente
si lo piensas bien, podemos tener algo
ejecutar y
terminar y aún así tener
acceso a las variables. Muy potente. Bien, así
que quiero salvar esto. Entonces voy a
reducir esto un poco. Sigamos adelante y
abramos la consola. Ahí está mi regreso inicial. No quiero poner
un nombre ahí. ¿Por qué no le puse
un nombre a una llamada así de bien, Steve, así? Bien, ahora lo guardaremos. La función se ha ido. Es contar regresiva, cuenta
regresiva, cuenta regresiva. 5 s está arriba. Tenemos buenos días, Steve, así
como acceso a todas esas variables
por cierre. Entonces como nos quedamos o como dije, la función se elimina
de la pila. Pero a pesar de eso, las variables aún
se conservan en memoria porque el motor o algo más podría
estar haciendo referencia a ellas. Entonces podrían ser
variables que podrían ser una función a la que esta
función llama. Esos son todos retenidos
en la memoria para que su acceso siempre y cuando sea
parte del alcance léxico, entonces tendrá acceso a ellos y no serán limpiados por el motor
JavaScript. Bien, hagamos
otro ejemplo. Voy a ir al archivo
HTML aquí, y voy a
añadir dos botones. Y quiero que el primer botón
tenga un ID de botón de uno. Entonces estoy usando el
atajo para hacer eso. M, es un plug-in para
Visual Studio Code. Cuando presiono tabulador, crea el botón para mí
con el ID de botón correcto. Y voy a
nombrar el botón. Haga clic en mí así. Bien, ahora vamos a
poner otro botón aquí. Y quiero que este también tenga una identificación, pero esta será BTM para hacer, Click Me también, así. Entonces esos son los dos botones
que hemos agregado. Guarde eso. A ver si esos
están apareciendo. Sí, están justo aquí. Y luego nos sale ese mensaje,
ese código sigue funcionando. Entonces, si venimos por aquí, voy a
comentarlo por sólo un minuto mientras
hacemos otra cosa. Entonces lo que quiero hacer es crear
una función de inicialización. Esta es una función
que vamos a ejecutar cuando se cargue
esta página y va
a inicializar algunas cosas, principalmente los oyentes de eventos. Entonces voy a llamarlo nicho. Ella miente. Y luego voy a poner
algunas variables aquí. A lo mejor puedas hacerte
una idea de lo que estoy haciendo aquí con Cierre. Voy a
configurar dos variables. Y ambas variables seguirán siendo
accesibles incluso después de que accesibles incluso después esta función de inicialización
esté completamente terminada. Entonces la función de inicialización
se va a ejecutar primero. Se va a configurar los oyentes de eventos que
estoy haciendo ahora mismo. A ver. Btn, uno es uno de esos
que quiero hacer. Agregar oyente de eventos. Y vamos a usar el evento
click va a configurarlos y luego
se va a terminar. Pero incluso con que esté terminado, vamos a
tener acceso a esas variables y veremos
cómo podemos lidiar con eso. Entonces una de las cosas que
vamos a hacer es C y T. Sólo
vamos a incrementar esa primera variable ahí y luego
iniciar sesión en la consola C y T. Eso es lo que haremos en
esta primera así. Y déjame seguir adelante y
punto y coma ahí, y
punto y coma ahí. Y sólo voy a copiar este y básicamente hacer un tipo similar de cosas
para el siguiente aquí abajo. Pero esta vez
vamos a hacer bt y dos, y esta vez vamos
a incrementar el conteo, pero vamos a hacer con
el monto del incremento. Entonces vamos a hacer un plus igual
incrementos como ese. Y luego volveremos a registrar el
conteo en la consola. Bien, tenemos esa configuración. Ahora, cuando se cargue la página, voy a llamar a inicializar. Entonces eso va a correr y se va a
quitar de la pila. Sin embargo, estas variables
se conservarán en la memoria
porque son referenciadas por estas
funciones aquí, estas funciones anónimas que forman parte del oyente de eventos. Entonces, quién sabe cuánto tiempo
pasará después de que esta función
haya finalizado, antes de que estos botones
o incluso haga clic. Realmente no importa
cuanto tiempo puedan ser años. Mientras esa
página permanezca activa, conservará en la memoria y tendrá acceso a ellas. Bien, así que vamos a guardar eso. Y ahora, obviamente, esa función
inicializada
ya se completó. Sigamos adelante y hagamos Click Me y nos
conectamos a la consola. Vamos a hacer clic en este de aquí. ¿Va a recordar este número que se
incrementó aquí? Lo hace. Se le añaden dos más. Y hago clic en
esto cuando le agrega uno. Entonces dos funciones diferentes, pero están abordando
el mismo alcance léxico. Entonces están abordando
la misma variable. Y debido al cierre, esas variables se retienen. Se accede a ellos por
ambas funciones. Puedes hacerte una idea. Ahora, el poder que el cierre
puede proporcionar en JavaScript, es realmente una
característica importante de JavaScript. Hemos proporcionado los
primeros ejemplos de cierre usando setTimeout y
también usando AddEventListener. Bueno, lo que quiero hacer a continuación en el siguiente tema es que
vamos a usar una función de orden superior para mostrar también la aplicación
del cierre. Entonces pasemos
al siguiente tema.
8. Usar el cierre con las funciones que se devuelven: Cuando hablamos de funciones de
orden superior, una cosa que hizo una
función de orden superior es si volvía a funcionar. Combinando esa
característica con el cierre, tenemos una construcción bastante
poderosa. Porque de pronto podemos devolver una función a partir de una función. Y esa función devuelta
tendrá acceso al alcance de la función original,
cualquier configuración de variable. Y él funciones declaradas. Tendremos acceso
a todos esos. Y uno de los beneficios de eso
es que no tuvimos que poner ninguna de esas variables son funciones en el ámbito global
para hacerlas accesibles. En cierto sentido, son privados. Sólo se puede acceder a ellos
por las cosas en su alcance. Y la función de retorno
puede seguir actuando sobre ellos y utilizarlos. Veamos un ejemplo. Bien, ahora fíjense el número de cosas que hemos declarado aquí. Tenemos una variable, tenemos tres funciones, y luego tenemos esta
función que se crea componiendo las tres
funciones anteriores a ella. Entonces tenemos bastante
que se declara aquí y está en el espacio global. Mientras usamos esta idea de la que
acabamos de hablar, vamos a ponerlo todo dentro de
una función y luego hacer
que devuelva una función
que hará esto. Lo mismo. ¿Bien? Entonces llamemos a esto, llamémoslo Obtener función
por simplicidad. Y voy a tomar
esto y cortar eso. Y luego sigamos adelante
y sangremos todo esto. Aquí abajo. Agrega la llave rizada de cierre. Entonces ahí está nuestra función. Tenemos esa configuración, pero ahora necesitamos
devolver una función. Entonces podemos hacer eso simplemente reemplazando esta
parte aquí con retorno. Y aquí va a devolver
esta función. Ahora asignarle eso para
multiplicar por cinco y así sucesivamente. Podemos declarar esta variable. Y podemos configurarlo igual a esta función que
acabamos de crear la función Get. Para que cuando se complete esta
función, la función get
se complete, va a devolver una función
y esa va a ser colocada y
multiplicada por cinco y mostrar. Muy bien, ahora esta función aquí, pesar de que esta función encima de ella está completamente terminada, se elimina de la pila. Va a tener acceso
a esto y esto y
esto y al num
uno que las variables pueden tener acceso a todo que va a
estar disponible para ello. Y entonces si cambiamos
la firma de esto. Entonces, si sólo estamos
pasando en un número, digamos y dos. Y luego aquí abajo, usamos num uno de este
declarado anteriormente. Ahora esto siempre se va a multiplicar por cinco
y algo más, lo que sea que se pase adentro. Así que eso hará que sea un
multiplicado por cinco y display, que va a
ser devuelto aquí. Ahora sólo estamos pasando
en un número así. Ahora sigamos adelante
y guardemos esto. Y le echaremos un vistazo. Abre la consola aquí. Y deberíamos tener acceso para multiplicarlo por cinco y Display. Y pasemos en seis. Y eso nos devuelve 30 formatos que pone la
puntuación después de todos modos, hace todas esas
otras cosas que formaban parte de esa función. Esta función aquí, la función
get, función, por lo que tiene acceso
a todas esas. Ahora algo más
que podríamos hacer para que esto
sea mejor es que podríamos usar el num uno aquí arriba. Podemos deshacernos de
la declaración aquí y solo
tenerla como parámetro. Ahora, cuando creamos la función multiplicarlo por cinco
y mostrar, pasamos en cinco. Pero también podemos
crear multiplicado por, vamos a hacer diez y mostrar. De pronto esto es
mucho más flexible. Apenas pasamos en diez ahí. Entonces ahora tenemos dos funciones que se han
creado a partir de esto. Y cada uno de
estos tiene acceso a todo lo que forma parte del alcance léxico de esta
función que se devuelve. Así se vuelve, se vuelve
muy poderoso de esa manera. Así que vamos a echarles un vistazo. Hagamos nuestra multiplicación por cinco. Hagamos siete esta vez. Entonces eso sigue funcionando para nosotros. Y ahora también tenemos
un multiplicar por diez. Hagamos siete en
esta también. Así que
ahora tenemos dos funciones que tienen acceso a
todo lo que está dentro de esto. El alcance de la
función get function, aunque esa función ya no
se esté ejecutando. El motor JavaScript
es lo suficientemente inteligente como para saber que podría haber algo que
todavía haga referencia al por lo que crea un
cierre sobre eso. Esos se mantienen en la memoria. Y por el cierre, podemos acceder a ellos. Ahora, déjame mostrarte
algo más que podemos hacer así como estamos tratando con
funciones de orden superior aquí, recinto. Déjame seguir adelante y
ir a la consola. Voy a llamar a get function. Y esta vez voy a pasar
en 20. Ahora, ¿qué
va a devolver eso? Bueno, va a devolver una
función como podemos ver aquí. Ahora, como eso es
devolver una función, podría hacer algo como esto. Ya que la función
está siendo devuelta, podría invocarla inmediatamente. El siguiente conjunto de
paréntesis invocará la función que
se está devolviendo. Y voy a pasar en cinco, y así eso debería ser igual a 100. Ahora tenemos una función. Si solo usamos la función gap esta manera tenemos una
función donde podemos multiplicar dos números cualesquiera
y mostrarlos. Ahora lo que estoy
tratando de mostrarles aquí es solo la flexibilidad por la función
de orden superior, por el cierre
que se ha creado. Y por eso dije que es un, es un constructo poderoso
en JavaScript y uno
con el que necesitamos estar familiarizados y necesitamos
poder usar. Bien, pasemos
al siguiente tema.
9. Características importantes de los cierres: Ahora, sé que he estado mucho
empeñando en esto, pero los cierres son importantes. Quiero utilizar este tema para
señalar dos características de los cierres que
los hacen importantes. Ahora bien, estas no son las únicas
características de los cierres. Pero dos que quiero
asegurarme de que entiendas. La primera característica es que los
cierres pueden ayudarnos a usar
eficientemente tareas intensivas de memoria
o CPU. Ahora déjenme dar un
ejemplo de ello. Así que aquí está nuestro código que
estábamos usando antes. Y digamos que como
parte de este código, tenemos un proceso que recupera datos de una base de datos o de una API en algún sitio. Y lo que recuperamos de eso a
medida que obtenemos esta enorme variedad. Ahora voy a
representar esta enorme matriz solo con una pequeña matriz. Pero piensa en ello como una tasa enorme. Estos son los datos que
regresan de la
API del sitio usando algún tipo de comando
asincrónico. Luego nos meteremos en cosas
asíncronas. Pero tenemos que lidiar
con ello de forma asíncrona porque
tarda mucho en volver. Pero cuando finalmente
vuelve, obtenemos esta matriz de números. ¿Bien? Y entonces estamos
cambiando esto a un índice. Y básicamente lo que
estamos haciendo es que estamos tomando de la enorme matriz el número que
vamos a elegir. ¿Bien? Ahora, permítanme recalcar nuevamente
que al recuperar estos datos, le toma un tiempo salir a la base de datos o al sitio
y obtenerlo y traerlo de vuelta. Entonces tenemos que lidiar con
ello de forma asíncrona. Ahora piensa si cada vez que queríamos multiplicar
números juntos, teníamos que hacer esta tarea
intensiva. Tuvimos que salir
y obtener esos datos. Cada vez que hicimos eso, tomaría los segundos
o lo que sea, aunque sea un
número menor de segundos, incluso milisegundos, esos pueden
sumar cada vez que
salimos y hacemos eso. Por lo que puede ser intensivo. Bueno, si nuestra función, la función se apaga
y la obtiene una vez, y luego la tenemos
almacenada en esta variable. Y luego a través del cierre, podemos seguir
accediendo a él usando la pantalla Multiplicar por cinco y luego
multiplicar por diez que cada vez que
queramos
multiplicar por cinco, no tengamos que
salir y obtener estos datos. Cada vez que llamamos a esta función. Es solo hacer referencia a lo que
ya tenemos almacenado en la memoria. Ya se hizo el
proceso para obtenerlo. Bien, así es como nos
puede ayudar a utilizar de manera eficiente intensivas en
CPU o que requieren mucho tiempo tareas intensivas en
CPU o que requieren mucho tiempo
o memoria intensiva. Al usar Closure, podemos hacer que eso
esté continuamente disponible para nosotros. Bien, ahora, la
segunda característica, característica de la que quiero hablar,
llamamos encapsulación. Ahora. Con el fin de entender lo que es
una encapsulación como permítanme simplemente ampliar esta idea. Tenemos donde
tenemos esta enorme variedad. Digamos que
esto es algo, esta matriz es algo que no
queremos que se cambie. Willy nilly, en cualquier
parte del programa. Solo hay un lugar donde
queremos poder cambiarlo, y ningún otro lugar en el programa ¿
debería permitirse que eso suceda? Bueno, podemos configurar una
función, algo así, donde pasamos un
nuevo número y luego
ese nuevo número se agrega a
la matriz y esa es la
única forma en que se puede actualizar. ¿Bien? Entonces solo hacemos un empujón
aquí con nuevo num. Así que no queremos que
la gente pueda acceder a es array y poder
agregarle números. De hecho, quizás, cada vez que alguien
le agrega un número, queremos verificarlo de alguna manera para asegurarnos de que cumpla con
algunos criterios. Entonces podemos tener una declaración
if aquí. Si num es mayor que 100, Tal vez eso es todo lo que estamos aceptando
o algo así. Entonces seguiremos adelante
y lo empujaremos. Así que controlamos la
adición de nuevos números a esa matriz usando
esta función. Entonces, la única forma en que la gente puede manipular la matriz
es con esta función. Tienen que pasar por esto. Ahora, ahora mismo
estamos volviendo a funciones que obviamente
no están permitidas. Una forma en que podemos hacer eso si
tenemos dos funciones, queremos regresar de
algo así, es que podemos devolver un objeto. Entonces, si solo cambiamos
esta función también, Update array así. Y cambiamos éste para
crear una función así. Entonces podríamos devolver un objeto. Y tendríamos arreglos de actualización y crearíamos diversión. Ambos serían
parte de ese objeto. De modo que cuando
llamamos a esta función, el retorno es un objeto. Así que consigue la función. Lo que recuperamos es un objeto. Y entonces podemos usar ese objeto. Podemos hacer OBJ para
actualizar matriz para llamar a esta función o OBJ punto crear fondo para
llamar a esta función. Entonces de todos modos, así es como haríamos eso en lugar de
hacer dos funciones de retorno. Pero el punto
al que quiero llegar es que ahora hemos creado una función que esta es la única forma en que podemos
cambiar esta matriz. Así que hemos encerrado esta
matriz dentro de una función. Lo hemos encapsulado. Entonces esto es encapsulación, lo protege de manera única, una manera de cambiarlo y
podemos verificar como eso se cambia. Y realmente estas otras funciones están encapsuladas. No están disponibles
fuera de esta función. La única forma en que
los usamos es con esto aquí. Esto tiene acceso a ellos, pero nada más
tiene acceso a ellos. Entonces estos están encapsulados. El ensayo, la idea
de encapsulación. Ambas características son características importantes a la
hora de cerrar. Bien, pasemos
al siguiente tema.
10. Comienzo de ejercicio: cierre 1: Bien, es hora de
un ejercicio más cercano. Ahora
te voy a
presentar el problema en este primer video, y luego en el siguiente tema
pasaremos por la solución. Ahora bien, este problema en particular es algo que
se puede ver en internet. Es un problema que muchas veces se presenta para ilustrar el cierre. Tal vez una parte de la
entrevista de JavaScript también. Entonces es muy práctico
en el sentido de que es el tipo de problema
que la gente presenta para ver si
entiendes el cierre. Entonces echemos un
vistazo a lo que es eso. Bien, así que tengo una matriz
aquí y la tasa de alumnos, y son solo nombres, nombres en esta matriz. Total de alumnos de cinco.
Eso es todo lo que hay. Entonces tenemos un for-loop y estamos haciendo un bucle
a través de esa matriz. Hemos declarado la variable. Pasamos por el bucle mientras es menor que la
longitud de esa matriz. Y luego incrementamos aquí. Y luego dentro de ese
bucle tenemos un tiempo de espera establecido. Y esta es la función
que se coloca en la cola una vez que ha expirado el
tiempo. Por lo que SetTimeout es manejado por
el navegador, la API web. Y cuando esos 2 s caducan, entonces esta función
aquí se coloca en la cola y el bucle de eventos, cuanto tiene espacio para
ello, la agrega a la pila y
esa función se ejecuta. Bien, entonces conocemos todo
ese proceso. Ahora vamos a seguir adelante y ver cuáles son los resultados de esto. Estamos viendo esto. ¿Qué va a
mostrar el registro de la consola? Entonces, si abro
la consola aquí, básicamente obtengo cinco declaraciones
indefinidas. Eso es todo lo que consigo en la bitácora. Entonces, cuando está
registrando en la consola, no puede encontrar nada
en la matriz, y simplemente
imprime indefinido. Entonces esto tiene dos partes para ello. Este ejercicio tiene dos partes. Primero, quiero que
piensen y puedan explicar por qué
hay cinco indefinidos, ¿por qué sucede eso? Y explicarlo en términos de cosas que hemos aprendido
sobre alcances. La segunda parte es entonces
usar el cierre para resolver este problema para
que eso no suceda. Para que en realidad nos
loguemos a la consola, los nombres que están
aquí en la matriz. Entonces dos partes a ese ejercicio. Ahora, voy a decir ahora mismo, hay una manera sencilla de
resolver este problema, pero quiero que uses el
cierre para resolverlo. Hablaremos de la forma sencilla al final de la solución, porque creo que es importante
entender eso también. Tanto el cierre como ambos
este otro concepto son importantes de
entender. Así que tómate un tiempo. Cuando estés listo, mueve el siguiente tema y nosotros
pasaremos por esta solución.
11. Final de ejercicio: cierre 1: ¿Cómo te fue en esa? Espero que sea capaz de
resolver eso. Hablemos primero de
por qué estamos consiguiendo
los cinco indefinidos. Hagámoslo primero. Así que fíjate que todo aquí no
se crea
dentro de una función, por lo que va a estar
en el ámbito global. Entonces eso está en el ámbito global. Esta declaración var, el ojo, eso está en el ámbito global. Bien, para que eso se
coloque en el ámbito global. Luego pusimos en marcha nuestro
primer setTimeout. Eso es manejado por el navegador.
Empezar a contar en dos segundos. El bucle for sigue adelante. Y así básicamente hace cinco de estos cinco setTime muy rápido tras otro
y están todos establecidos para 2 s. ¿
Bien? Ahora, para cuando
lleguemos a ese último, se incrementa la última iteración de este bucle
for i. Y así yo en ese
momento me convertí en cinco. Y yo estoy en el ámbito global. Entonces una vez que se
hace este 2 s para el primero, esa función se
coloca en la cola. Se recoge
por el bucle de eventos y se coloca en la pila. Invoca. Esta línea aquí se ejecuta. Aprendices cinco no está definido. Tenemos 012345 es indefinido. Por eso estamos
consiguiendo lo indefinido. Entonces, lo que queremos hacer
es que queremos configurar cierre para que cerremos sobre una variable que luego se
pueda usar aquí. Y no va a ser usando
la variable global I, que se cambia cada vez iteramos a través del for-loop. ¿Bien? Y al establecer una función, definimos un nuevo alcance. Y así
se maneja el cierre para ese alcance y la variable
que usamos dentro de ese. Entonces, sigamos adelante y
veamos cómo podríamos hacer eso. Hay un par de
maneras de hacer esto. Pero el primero, sólo
voy a
crear una función aquí. Y esta
vez voy a hacer una declaración de
función sólo para que sea más corta. Voy a
llamarlo show learner. Y entonces solo sigamos
adelante y cortemos esto. Y vamos a pegar esto
dentro de esa función. Entonces, debido a que hemos
configurado una nueva función, hemos definido un nuevo alcance. Ahora podemos colocar una
variable dentro de eso. Así que dejemos que el alumno sea igual y solo voy a
ponérselo a los alumnos. Y luego el índice I. Así que vamos a asignar uno de los nombres a
esta variable aprendiz. Y eso es exactamente lo que
vamos a mostrar aquí. Y así por el cierre, cuando esta función
se dispare, tendrá acceso
a esta variable. Y cada vez
que esta
función invoca, creará una
nueva variable para el nuevo alcance
que se cree. Y así aquí abajo, tendría que
poner show learner. Entonces se invoca cada vez
a través de este bucle for. Ahora, cuando nos metemos en expresiones de
función invocadas
inmediatamente, hay una
manera más sencilla de hacerlo, que veremos
en ese momento. Pero por ahora, sólo estoy
invocando la función aquí. Se llama a esto, establece una variable dentro de
ese alcance de función. Esta función porque hace
referencia a esa variable. Y por el cierre, esa variable quedará retenida en la memoria para que
tenga acceso a ella. Y eso debería resolver
el problema por nosotros. Entonces si digo eso después de 2 s, obtenemos todos los nombres que se muestran. Bien, entonces ese es un enfoque. Voy a copiar esto.
Entonces tengo una versión de cada uno de estos en el
código que puedes mirar. Yo sólo voy
a comentar esa de ahí. Entonces otro enfoque se
habría establecido una variable idx tal vez para index y
simplemente establecer eso a I. Bien, entonces esta variable
ahora es parte de este alcance. Entonces eso va a lograr
lo mismo. La única diferencia
está aquí abajo. En lugar de i, usamos idx para hacer referencia a la
posición en la matriz. Y eso va a funcionar
igual de bien para nosotros. Si guardo eso, saltamos aquí después de 2 s, podemos ver los nombres mostrando. Bien, ahora mencioné que también hay una solución simple
para esto. Entonces déjame mostrarte cuál es
esa solución simple. Déjame copiar esto. Entonces estas dos primeras soluciones, Usando más cerca, permítanme simplemente
hacer un comentario ahí. Uso de cierre. Comenta eso. Entonces ya no estamos lidiando
con eso. El segundo es simplemente
usar la propiedad de LET. Ahora bien, si recuerdas una
de las diferencias de las que hablamos con let y
const en contraposición a var, es que los contras latinos
tienen alcance de bloque. ¿Qué significa el alcance bloqueado? En el caso de este for-loop? Voy a quitar
esto muy rápido y dejarme deshacerme de eso. Sólo vamos a ponerlo de
nuevo a la manera en que estaba. Y entonces quiero usar yo
aquí para hacer referencia a esos. Ahora, volvamos a la
idea de alcance de bloque. ¿Qué significa walk scope? Bueno, el alcance está justo aquí. Y así
porque tiene alcance de bloque, si cambiamos esto a
lat en lugar de var, ya está
dentro de esto. Y esta función
seguirá teniendo referencia
a ella a través del cierre. Entonces la variable I
se mantendrá en la memoria. Y cada vez a través del bucle, básicamente se está declarando
una nueva variable i. Debido al alcance de bloque
que obtenemos con let. Bien, y así cada una de esas funciones tendrá
una referencia a esa I. Y eso nos va a resolver
el problema. ¿Bien? Entonces esto resuelve el problema usando una característica de let que
a veces nos olvidamos. Olvidamos que el alcance de bloques puede hacer este tipo
de cosas por nosotros. Pero déjame mostrarte,
voy a salvar eso. Salta de nuevo después de 2 s.
Mismos resultados, mismos resultados. Ahora creo que
mencioné cuando estaba hablando de que esta solución
realmente no usa close. Bueno, sí usa cierre. Todavía estamos cerrando
sobre una variable. Ahora, los estilos de función
hacen referencia a él. Pero la razón por la que esto
funciona y var no es porque lat tiene este alcance de
bloque aquí. Var no tiene alcance de bloque, por lo que se enfocó
al contexto global. Entonces esa es otra solución. Ahora bien, si no pudiste llegar
a esa solución, espero
que al menos la entiendas. Espero que veas como estos usan el cierre para
resolver el problema por nosotros. Y me gustaría que
hicieras un ejercicio más, así que vamos a hacer uno más a continuación. Sigamos adelante.
12. Comienzo de ejercicio: cierre 2: Voy a hacer que hagas un
segundo ejercicio sobre cierres. Como pueden ver, he agregado tres botones
a esta página HTML. Y este ejercicio involucra
esos tres botones. Déjame seguir adelante y
saltar al archivo de código. Tengo una descripción de lo que
me gustaría que hicieras ahí. Y estos son los mismos
archivos de código que usarás
para el ejercicio. En primer lugar, aquí arriba en la parte superior, he seguido adelante y he creado
tres constantes que tienen los botones que he
creado en una página HTML. Estos tres botones de aquí, sus referencias,
esos tres botones, he seguido adelante
y los he creado. Puedes usarlas o puedes
crear las tuyas propias lo que sea. Acabo de agregar que por
si algunos no estaban seguros cómo seleccionar esos
botones del DOM. Ahora bien, esto es lo que me
gustaría que hicieras. Cada vez que se haga clic en uno de esos
botones, debería mostrar dos números. El primer número que
debe mostrar es la cantidad de veces que se ha pulsado ese
botón. Y luego un segundo número es el valor acumulativo
de los tres botones. Entonces debería decir
algo como esto. Me han hecho clic tres veces. Los tres botones han sido pulsados diez veces,
algo así. Y es importante que uses el cierre para que esto suceda. Ahora, ten en cuenta. Hay cientos de formas de
resolver este problema. Hay cientos de formas fuera del cierre para resolverlo, pero hay cientos de formas de
usar Closure para resolverlo. Entonces tu solución probablemente
va a verse un poco
diferente a mi solución. El punto es, quiero
que uses cierre. Quiero que te pongas a practicar
haciendo eso y pensando en tu código con cierre como
herramienta para resolver estos problemas. Entonces así es como me gustaría
que abordaras esto. Muy bien, adelante y
dale algo de tiempo a eso. Una vez que estés listo para seguir
adelante y ver la solución, pasa al siguiente tema.
13. Final de ejercicio: cierre 2: Bien, pasemos por esto. Ahora estoy bastante seguro de que mi solución va a ser
un poco diferente a la tuya. Sospecho que lo que muchos de ustedes hicieron es que crearon
una función externa. Declaras tres
variables, cuatro variables, en realidad una para la cuenta
total y luego tal vez una variable para
cada conteo de botones. Entonces los
incrementaría en
los momentos apropiados y mostraría el mensaje apropiado. Voy a tomar un enfoque
un
poco diferente para resolver esta solución. Quería asegurarme de
usar el principio DRY. No quería repetir cosas que no necesitaba repetir. Voy a tener
una sola función que va a mostrar. Voy a tener un
solo constructo. Se va a agregar un
oyente de eventos a cada uno de estos. Y básicamente he
eliminado el uso de cualquier declaración IF en absoluto como capaz de hacer lo que
hice por el cierre. Como estoy seguro tu solución
usa también el cierre. Así que
sigamos adelante y comencemos para poder mostrarte mi solución. Podemos aprender de ello juntos. Así que primero voy a configurar una función de inicialización
que va a ser la función externa que
va a establecer todo esto. Y entonces voy a querer invocar
eso para que las cosas se inicien. Así que voy a poner eso aquí abajo. Doble impresiones para indicar que estamos invocando
esa función. Ahora lo que voy a hacer con estas declaraciones aquí es
que voy a configurar una matriz, solo voy a llamar botones. Y esta matriz va a contener cada una de
estas declaraciones. Ahora la razón por la que estoy haciendo
esto es que voy a
declarar a los
oyentes avanzados con un bucle. Y así quiero poner estos en una matriz solo para
que eso sea más sencillo para mí. Porque entonces puedo simplemente
recorrer esa matriz, agarrar cada elemento, cada elemento, agregar el oyente de eventos,
entonces estoy listo para irme. Así que ahí está mi matriz. Ahora necesito configurar
otra variable. Este va a ser
el conteo total. Esto tiene que ser parte de esto sobre todo el alcance de
esta función general. Porque va a necesitar ser incrementada por
los tres botones. Entonces inicialmente voy a
poner eso a cero. Bien, Ahora, mientras estaba
pensando en esto, me imaginé, bueno cada uno de
estos botones van a mostrar el mismo mensaje. Y así realmente debería tener
una función que pueda mostrar ese mensaje en cada uno
de estos botones
va a incrementar la variable de conteo
total. Y entonces debería tener una
función que haga eso también. Y entonces pensé, bueno
puedo poner esas cosas en una sola función. Así que voy a configurar eso ahora. Incremento y visualización. Si puedo escribir contadores, así es como lo
voy a llamar. Justo ahí dentro,
puedo
incrementar de inmediato la variable de
conteo total. Y luego puedo iniciar sesión en
la consola el mensaje. Y voy a usar una cadena de plantilla solo para hacer
esto un poco más fácil. Y voy a copiar, sólo
voy a copiar exactamente la misma frase aquí abajo. Eso es lo que quería
mostrar de todos modos, así que sólo voy a copiar eso. Ahora en el lugar del conteo
total, éste de aquí. Necesito poner el conteo total
variable. ¿Y qué voy a poner aquí? Bueno, creo que lo que voy a
hacer es que voy a pasar el conteo de cada botón. Y así entonces puedo reemplazar esto
con ese pasado invariable. Ya que eso es un parámetro. El alcance de esa
variable está aquí, mientras que el alcance del
conteo total es todo eso. Entonces, cuando cree los
oyentes de eventos aquí abajo, podrá
incrementar la cuenta. Y esta función
aquí también tendrá acceso al conteo total a
través del cierre. Entonces va a estar disponible. Bien, así que ahora
sigamos adelante e incrementemos los oyentes de eventos. Y como dije, configuré una matriz para poder
hacerlo en un bucle. Entonces ciclo a través de esto. Y esto me permite hacer
el mismo código solo una vez. Porque configurar
esos oyentes de eventos sería el mismo código. Ahora bien, esto es lo que quiero
hacer dentro de este bucle for. Voy a declarar una variable
y voy a usar lat. Entonces el alcance de ese
será ese bloque. Y voy a ponerla a cero. Entonces esta es una variable
diferente a esta porque
tienen un alcance diferente. ¿Bien? No están
en conflicto entre
sí a pesar de que
tengan el mismo nombre. Y lo estoy configurando porque en el EventListener
voy a configurar una función. Eso entonces tendrá acceso
a esta variable e
incrementaremos esa variable y
luego la pasaremos a aquí. Bien. Entonces, cada vez que se llame a
esto, va a tener una variable
diferente o posiblemente una
variable diferente pasada adentro. Y debido al cierre, voy a poder hacer
un seguimiento del conteo total. Voy a poder hacer un seguimiento
del recuento individual. Entonces ahora sigamos adelante y
configuremos esos oyentes de eventos. Entonces BTN, usando el bucle for, btn ahora contiene cada uno de estos elementos DOM a medida que
itera a través de esa matriz. Entonces BTN, agregar oyente de eventos. Entonces queremos usar
los eventos click, y aquí está mi función
anónima. Ahora, ¿qué vamos a hacer dentro de esta función anónima? Bueno, primero vamos a
incrementar esta variable aquí. Esta función
tendrá acceso a
esa variable a través del cierre. Entonces, para hacer un seguimiento
de las cuentas. Una vez que hayamos incrementado,
seguiremos adelante y llamaremos a los contadores de visualización de incremento. Y vamos a
pasar en esa variable. Esta variable aquí que ha sido incrementada se
pasará a aquí, y luego se mostrará
aquí. Y esta variable
que forma parte de ese alcance simplemente se
incrementará cada vez que se llame a
la función. Y debido a que he recorrido todos los elementos de la matriz, todos estos botones tendrán
este mismo oyente de eventos. Entonces todos vamos a
llamar a esa misma función. Debido a que esto es un bucle, esta será una
variable diferente cada vez que
pase por ese bucle. Y luego las funciones
para cada oyente de eventos. Bueno, tengo acceso a
ella por el cierre. Bien, sigamos adelante y
veamos cómo funciona eso para nosotros. Voy a
seguir adelante y ahorrar eso. Y volveremos a saltar por aquí. Y digamos que quiero mostrar
la consola para que podamos ver
los recuentos que estamos recibiendo. Así que déjame desplazarme hacia abajo
hasta que aparezcan los botones. Y si hacemos clic en el botón
uno, ¿qué obtenemos? Una vez se
ha hecho clic en los tres botones una vez. Déjame darle click
otra vez. Dos veces. Los tres botones
voy a hacer clic dos veces. Ahora anotó un botón a
una vez, tres veces. Vamos al botón tres. Una vez, cuatro veces
botón para otra vez, dos veces, cinco veces. Parece que está funcionando
dos veces, seis veces. Bien, así que un pequeño
ejercicio divertido usando cierre. Entonces espero que este ejercicio sea
NOSOTROS educativo. No sólo
tuviste la oportunidad de
intentar resolverlo por tu cuenta. Pero también tal vez puedas aprender algo del
enfoque que tomé también. Porque como dije, probablemente
hay 100 formas diferentes de
resolver este problema. Bien, pasemos
al siguiente tema.
14. Expresiones de funciones invocadas inmediatamente: Las expresiones de
función invocadas inmediatamente son un
patrón importante en JavaScript. Lo he mencionado
brevemente durante
algunos de los temas pasados. Bueno, ahora lo vamos a
ver con más detalle. inmediato. Las expresiones de
función de invocación se llaman IFIS en el mundo
JavaScript. Esa es la forma en que
pronuncia ese IFE
que ve al final ahí
en esa línea de título. Iffy. Y si simplemente está definiendo una función y luego
invocándola de inmediato, no
esperamos a llamar más tarde. Se define y a
granel al mismo tiempo. Veamos un
ejemplo sencillo y luego
voy a hablar
de algunas de las razones que utilizamos. Si está bien, voy a crear aquí una
función muy sencilla. Básicamente va a sumar dos números y
devolverlos también. Entonces volveremos, vamos a hacer
sólo cinco más cinco. Ahora bien, si guardamos esto, y voy a saltar aquí y echar un
vistazo a la consola. Si miramos la variable sum, lo que contiene, vemos
que contiene la función. Ahora bien, si queremos invocar eso, entonces tenemos que sumar las purinas. Ahora bien, ¿y si
pudiéramos definir esto? Y luego solo ponemos los paréntesis
dobles al final de la misma aquí para que estemos definiendo la función y luego la estemos invocando
al mismo tiempo. Eso significaría que se invoca de
inmediato. Y esta es una expresión de
función. Entonces una expresión de
función invocada inmediatamente. Entonces probemos eso. Voy a seguir adelante y poner las dos
citas después de eso. Ahora, ¿qué va a haber
en la variable sum? ¿Va a ser la función? Sepa, va a
ser el valor que devuelva si esto
inmediatamente se invoca. Así que vamos a salvar eso. Y luego echemos
un vistazo a algunos. Ahora, contiene la respuesta o el valor de retorno de esa función porque
fue invocada inmediatamente. Entonces esta aquí es una expresión de
función invocada
inmediatamente. No funciona para una declaración de
función. No podemos hacer este tipo de cosas. Veamos el regreso. Hagamos algo así. Quiero que te
enseñes lo que pasa si
establecemos una declaración. Entonces, si guardo ese error de sintaxis
no capturado, token
inesperado en la línea nueve. Entonces, ¿por qué a nueve no le gusta esto? No sabe lo que
estamos haciendo aquí. Entonces no se puede hacer con
una declaración de función, tiene que ser una expresión de función. Así que cada vez que estamos
invocando inmediatamente algo es una expresión de función. Ahora, déjame mostrarte tipo de cosas que
se pueden hacer con esto. Voy a hacer una suma diez, y voy a poner eso
igual a una función. Y ahí vamos a tener un parámetro para un
número que se pasa. Y luego dentro de
aquí vamos a declarar una variable y pondremos esa igual a
diez, así como así. Y luego
regresaremos num más uno. Entonces por eso lo estamos
llamando unos diez. Ahora, ¿qué pasa si inmediatamente
invocamos estas huellas alrededor de eso? Guárdalo. Echemos un vistazo a unas diez. Nan nos está diciendo
que no es un número. Qué nos está diciendo
que por un tiempo
no pasamos un valor en por esto. Y así está tratando de agregar
indefinido a diez, dice Nan. Entonces pasemos un valor
y haremos cinco. Guarde eso. Ahora conseguimos 15 con algo de tiempo. Ahora, quiero hacerte consciente de algo con esta variable
que acabo de poner aquí. No hay nada que pueda cambiar esta variable
una vez establecida. Son diez. Y no es sólo porque
usé una constante definida, obviamente un agente
evitar que de ser reasignado
obtendrá un error de sintaxis. Pero también es porque está
contenida en esta función. El hecho de que se defina en esta función significa que
no tenemos acceso a ella, ningún otro código o incluso
podríamos vestir esa variable
porque está dentro de la función. ¿Bien? Entonces, la razón por la que muestro
esto es que esto ayuda a ilustrar los casos de uso para expresión de
función invocada
inmediatamente es en realidad
hay dos de esos. Yo sólo voy a
introducirlos aquí. Casos de uso a eso
creo que son importantes. Uno son los datos privados. ¿Bien? Se trata de datos privados. Esto no se puede cambiar. Está dentro de la función, no se
puede
meter, es privado. Otro caso de uso es evitar variables
globales y colisión de
variables. Así que somos capaces de ejecutar código sin declarar variables
globales cuando usamos una expresión de función
invocada inmediatamente. Ahora permítanme ilustrar
ese caso de uso. Entonces voy a copiar
en algún código aquí. Simplemente lo pegaré
debajo de estos casos de uso. Ahí vamos. Título también. Yo también soy el título del selector de consultas. Estoy agarrando,
miramos archivo HTML. Estoy agarrando este div aquí
mismo que tiene la expresión de
función invocada inmediatamente línea de marea. Bien, estamos agarrando eso. Entonces le estamos agregando oyentes de
eventos. Uno es para mouseover,
otros para mouse out. En ambos casos,
lo único que hace es cambiar el cursor y volver a cambiarlo. Y luego tenemos un evento click que simplemente registra en la consola el texto
interno de este. ¿Bien? Entonces, si guardamos eso,
salimos aquí. Observe que mi cursor cambia. A medida que voy sobre eso. Cuando hago clic en él pone
la información, el innerHTML de ese
elemento DOM en la consola. Ahora hemos declarado una
variable aquí para hacer eso, para agarrar este div y
poder usarlo. Pero pongamos una
función alrededor de esto. Empecemos
declarando una variable. Voy a cambiar
esto en un momento, pero vamos a
empezar de esta manera. Digamos un knit, es una función inicializada. Y déjame poner todo esto. Voy a sangrarlo. Así que eso puede estar dentro de
estos tirantes. Formatear un poco para nosotros. Y luego aquí está
la rizada de
cierre para esa función. Ahora tenemos una función init. Ahora bien, obviamente si
guardamos esto, ya no tenemos la
funcionalidad aquí porque no se ha invocado. No llamamos a esa función. Bueno, sabemos que de inmediato
podemos invocar eso haciendo
este tipo de cosas. Entonces agrego el príncipe
al final ahí. Ahora veamos si
tenemos esa funcionalidad. Me subo, el cursor
cambia, hago clic en él. Sí, lo tenemos. Entonces pudimos invocar eso de
inmediato, pero todavía tenemos
una variable aquí. Bueno, no estamos capturando
nada que sea variable. No hay nada que
regresemos de esta función que necesitemos
tener la variable para ello. Simplemente eliminemos esa variable. Y veamos si eso funciona. Nosotros lo guardamos. ¿Qué obtenemos? Una sentencia de
función de error de sintaxis devuelve un requiere
un nombre de función. Entonces lo que nos está diciendo, lo que nos está diciendo ese
error de sintaxis es que se trata de una declaración de
función. Está esperando un
nombre de función justo después. Se espera una declaración de
función porque ve que la palabra clave
function es primero. Bueno, vamos a convertir esto
en una expresión. Y por qué podemos hacer eso es simplemente poner paréntesis a su alrededor. Ahora normalmente me gusta poner mis paréntesis
alrededor de la función y luego tener las marcas para
invocarla justo después de eso. Pero hay mucha gente
que prefiere hacerlo. De esta manera. Ambos funcionan. No importa de qué
manera elijas hacerlo. Ambos funcionan. Entonces ahora vamos a guardar esto. Ya no obtenemos
la sintaxis ahí. Yo subo, consigo cambiar el
cursor. Yo hago clic en él, lo veo
abajo en la consola. Entonces ahora tenemos código que se está
ejecutando dentro de una función. Y no tuvimos que declarar variable para que eso sucediera. Esta variable se encuentra ahora
dentro de la función, no contamina
el espacio global. Así que evitamos colisiones variables, es
decir, que alguien más trabajando en un proyecto
o algún frío que
trajimos tenía estaba usando el mismo nombre de variable
y esas dos variables, Clyde, la última uno
a declarar o el último en recibir un valor es el
que tiene prioridad. Así evitamos esas colisiones y evitamos las variables globales. Ahora también podemos
tener datos privados. Obviamente nadie puede
acceder a esta variable, pero estos elementos DOM disponibles
fuera de esta función, solo
necesitarían seleccionarla. Pero puedo declarar
una variable aquí, ponerla igual a algo. Sólo puntuación o algún tipo. Ahora no se puede
acceder a esto de aquí en adelante. La puntuación va a
ser un signo de exclamación. Bueno, también podríamos
configurar una función dentro de esta función y
devolverla fuera de la función. Eso
nos permitiría cambiar esto. Y entonces gobernamos cómo se cambian esos datos
privados, que es un patrón muy común. De hecho, este es un patrón que se usa en el patrón de módulo
tradicional, que hablaremos cuando tratemos de
módulos en este curso. Como ya mencioné, con cierres
va a estar viendo
eso y vas a estar mirando inmediatamente la expresión de función
invocada cuando tratemos con los patrones de módulos
tradicionales. Por lo que es un gran patrón
aprender a aplicar estos conceptos. Pero este signo de
puntuación es privado. Si guardo esto, sal a darle click sobre él. Ahora estamos viendo ahí el signo
de puntuación. Entonces eso se
invoca inmediatamente expresiones de función. Ahora lo que me gustaría
hacer en los siguientes temas, vamos a ver algunas de
las piezas de código que
usamos en temas pasados donde quizás haya mencionado que esto podría mejorarse con inmediatamente invocó la expresión
de la función. Veremos cómo
podemos mejorarlos. Vamos a ver los cambios que
necesitamos hacer para usar un iffy. Bien, así que
pasemos al siguiente tema.
15. Aplicar las IIFEs: Ahora que he introducido el IFIS, vamos a aplicarlos a algunos de los ejemplos de código que hemos
estado usando en esta sección. Estos son ejemplos de cierre
y ahora vamos a agregar IFIS a ese mismo código. Ahora, el primer ejemplo
es el saludo retrasado. Ahora bien, este es un ejemplo sencillo. Si recuerdas,
tenemos una función. Llamamos
pase de saludo retrasado en un nombre usando setTimeout ese saludo
se retrasa 5 s. Ahora bien, si esto fuera un funcional
quería llamar desde algún lugar, entonces no usaríamos
un vacío para eso. Pero quiero usar NFV. Digamos que quería que esto se
mostrara cuando se cargue el archivo. Y así quiero usar NFV para este ejemplo porque tiene
este pase en una variable. Entonces quiero hacer un
ejemplo de eso. Sigamos adelante y
veamos cómo haríamos eso. Muy sencillo. Sólo tenemos que quitar esto. Ya no necesitamos eso. Y también podemos eliminar
esta parte. Ahora, queremos convertir esto en una expresión para que sea válida y así pongo paréntesis
alrededor de eso así. Y luego para invocarlo, volvemos a poner paréntesis. Ahora como saben, hay
diferentes formatos para esto, este último Perrin también podría
salir por aquí. Simplemente prefiero esta estructura
en particular. Ahora lo que tenemos que hacer
es pasar en la variable, y así solo pongo eso
dentro de los paréntesis. Eso es todo lo que necesitamos para hacer eso. Y ahí tenemos nuestro saludo
retrasado. Así que déjame volver aquí y
vamos a abrir la consola. Aquí está nuestro saludo de cuando
cargamos la página por primera vez. Ahora, sigamos adelante y guardemos
esto y se recargará. Y luego después de 5 s, deberíamos volver a recibir el
mismo saludo. Básicamente solo estamos
quitando la línea que invoca esta función y la
estamos manejando aquí. Eso es realmente lo que
estamos haciendo con una expresión de
función invocada inmediatamente. Bien, ahora voy
a comentar esto. Y voy a copiar en otro trozo de código que
usamos como ejemplo. Y esta fue una función
inicializada. Adelante y pega eso.
Y si eres miembro, es inicializar dos botones. Y cuando se les
haga clic, incremente la variable de conteo y
luego inicie sesión en la consola. Ahora bien, para poder usar esto, necesito venir aquí y descomentar esos
botones para que aparezcan en la página HTML. Así que adelante y refresca eso. Y digamos éste. Vamos a ver si
esos están apareciendo. Los tenemos aquí mismo. Bien. Solo asegúrate de que ese código esté
funcionando antes de que sigamos adelante. Sí. Bien. Entonces estamos bien. Ahora cuando tenemos
algunas cosas para inicializar y no hemos inicializado función así. Esa suele ser una buena
aplicación para un dudoso. Como esta función va, solo se va a ejecutar una vez y
es cuando se carga la página. ¿Por qué almacenarlo en una variable? Entonces podemos llamarlo más tarde. O por qué declarar la función
para que podamos llamarla más tarde. Vamos a invocar el código, ejecutar el código, y
terminar con él. Entonces, sigamos adelante y eliminemos
esa declaración ahí, y vamos a quitar esto aquí abajo. Una vez más, todo lo que tenemos que hacer es rodear esto con Krenz. Eso lo hace válido. Y luego ponemos los planes
después para invocarlo. Ahora esto realmente
va a lograr mismo, lo mismo para nosotros. Entonces vamos a guardar esto,
la página se recarga. Y sigamos adelante y
probemos estos botones. Y siguen trabajando. Entonces dos ejemplos rápidos donde
tomamos algo que hicimos con cierres y agregamos una expresión de
función invocada inmediatamente. Y sobre todo el segundo
ejemplo es ideal para el IFIS. Bien, sigamos adelante
y déjame darte oportunidad de probar un
ejercicio sobre estos.
16. Comienzo de ejercicio: IIFEs: Una vez que entiendes
la estructura de una expresión de
función invocada inmediatamente, no
son tan
difíciles de crear. Normalmente estás convirtiendo
algo que ya está ahí en uno y así eso lo
hace aún más fácil. Pero quiero que
hagas un ejercicio. Este es un
concepto importante y creo que es importante hacer un
ejercicio sobre este concepto. Entonces echemos un vistazo a lo
que me gustaría que hicieras. Bien, aquí hay un
código inicial y básicamente todo lo que está haciendo es crear un mensaje dentro de
esta variable de mensaje, diciendo que algo como
hoy es lo que sea la fecha y luego
el día del mes. Eso es todo lo que está haciendo. Esto
es algo que podría mostrarse en la página inicial
o algo así. Entonces, lo que me gustaría que hicieras
es que conviertas esto en
una duda y para ver si
está funcionando correctamente, solo tienes que registrar los resultados
en la consola. Entonces lo enviaremos a la consola. Debe producir
tan pronto como la página se cargue y se
desconecto a la consola. Normalmente es posible que desee mostrar este mensaje dentro de algún
div o algo así. Haremos la consola y
eso va a ser lo suficientemente bueno. Bien, adelante
y pruébalo con esto. Y cuando estés listo para revisar, pasa al siguiente tema.
17. Fin de ejercicio: IIFEs: Bien. Ojalá eso no fuera demasiado duro. No pretendía que ese
fuera demasiado difícil. Ahora, solo por mencionar una de las ventajas de
convertir esto en una FE es que de pronto hay tres variables que
actualmente están en el espacio global, que no van a estar en
la meta del espacio. Tan grande ventaja, están
haciendo de esto un dudo. Entonces sigamos adelante y hagamos eso. Voy a entrar primero a
la función. Y luego mis llaves, voy a seguir adelante
y tomar el código ahora y ponerlo dentro
de esa función. Observe que no le di un nombre a
la función, lo
que generalmente significa que estoy en el proceso de
crear un dudo. Pero sí necesito
rodearlo entre paréntesis, convertirlo en expresiones
para que no obtengamos un error de sintaxis y luego
paréntesis para invocarlo. Ahora lo único que sí
mencioné que queremos hacer es que solo queremos mostrar
esto a la consola. Entonces déjame seguir adelante y hacer eso. Mensaje de registro de puntos de consola solo para asegurarse de que
funciona correctamente. Y eso lo guardaremos. Salta aquí y echa
un vistazo a la consola, ver si tenemos un mensaje. Hoy es lunes 19. Y eso es efectivamente lo es
el día de la semana y
la fecha del mes. Y eso está funcionando para nosotros. Tan bastante simple. Pero un
patrón muy importante y JavaScript invocaron
inmediatamente
expresiones de función o si él es, bien, sigamos adelante.