Kitabı oku: «JavaScript: Guía completa», sayfa 3
Cadenas multilínea
Otro aspecto interesante de las plantillas de cadena es que se pueden crear fácilmente cadenas multilínea sin necesidad de recorrer a otros operadores.
Para evitar que la cadena multilínea se refleje en el HTML en una única línea, necesitamos un bloque de código <pre>
.
Así, añadimos a la parte del HTML de nuestro archivo la línea siguiente:
<pre id="output1"></pre>
Después, en la parte de JavaScript, agregamos este código:
const mensaje1 = `dime¿qué tienes programado para hoy?`……document.getElementById('output1').innerHTML = mensaje1;
Puedes encontrar este ejemplo en el archivo CaritaMensajeInicio .html
La Figura 4.2 muestra la salida de este fragmento en un navegador.
Figura 4.2 – La cadena multilínea en el navegador.
Muy a menudo se recurre a las cadenas multilínea para crear un código HTML con formato.
Para hacer una prueba, sustituye la etiqueta <pre>
por una etiqueta <div>
que podremos rellenar después con otros objetos HTML:
<div id="output1"></div>
Ahora, corrige también el valor de la constante mensaje1
:
const mensaje1 = `<h1>hola</h1><p>¿qué tienes programado para hoy?</p>`
Puedes encontrar este ejemplo en el archivo CaritaMensajeInicioHTML .html
Ya no necesitamos realizar más cambios. Prueba el archivo en un navegador y muestra la estructura (pulsando F12 en el teclado, en la mayoría de los navegadores) o el código fuente de la página (Figura 4.3).
Observa que en la etiqueta <div>
el código HTML que hemos insertado permanece distribuido de forma ordenada en varias líneas.
Figura 4.3 – La estructura de la página en el navegador.
Insertar el backtick o acento grave
Para insertar el carácter backtick con el teclado italiano, hay que pulsar la combinación de teclas ALT + 96 desde el teclado numérico.
Esto es un problema con los PC portátiles, muchos de los cuales no disponen de teclado numérico (algunos cuentan con teclas que corresponden al teclado numérico pulsando a la vez la tecla fn, pero no es lo habitual).
Por esta razón, vamos a ver cómo podemos obtener este caracter. Te proponemos dos soluciones: el mapa de caracteres y el teclado italiano 142.
La solución más inmediata, aunque quizás poco práctica, es la que implica el uso del mapa de caracteres, desde el cual podemos copiar el carácter que necesitamos (Figura 4.4).
Para abrir el mapa de caracteres, en Windows 7, selecciona Inicio > Todos los programas > Accesorios > Herramientas del sistema > Mapa de caracteres o, en Windows 10, Inicio > Todas las aplicaciones > Accesorios de Windows > Mapa de caracteres.
Otras solución, que, para nosotros, es más cómoda si se debe utilizar el backtick con frecuencia, consiste en utilizar el teclado italiano de 142 caracteres, que sería el teclado italiano para programadores.
Figura 4.4 – Backtick en el mapa de caracteres.
Para activarlo, debemos acceder a la sección Reloj, idioma y región del panel de control. (Figura 4.5).
Figura 4.5 – La sección Reloj, idioma y región del panel de control.
Para abrir esta ventana, con Windows 7 selecciona Inicio > Panel de control > Reloj, idioma y región, y con Windows 10 selecciona Inicio > Sistema de Windows > Panel de control > Hora e idioma > Región e idioma > Opciones adicionales de fecha, hora y configuración regional.
En esta ventana, selecciona Cambiar métodos de entrada y, después, en la ventana siguiente, haz clic sobre Opciones correspondiente al idioma italiano.
En la nueva ventana, haz clic en Agregar un método de entrada (Figura 4.6). En la ventana siguiente, localiza el teclado Querty Italiano 142 y haz clic en Añadir.
Figura 4.6 – Elige un nuevo método de entrada para el idioma italiano.
Una vez añadido el teclado, cierra las ventanas del panel de control y, en la barra de aplicaciones, localiza el icono del teclado actual: para el teclado italiano, aparecerá el icono IT. Pulsa sobre él y elige el teclado italiano 142 (Figura 4.7).
Figura 4.7 – Activar el teclado italiano 142.
A partir de ahora, para insertar el backtick, sencillamente deberás utilizar la combinación de teclas AltGr + ù.
Si has elegido insertar el teclado italiano 142, ten en cuenta que las combinaciones de teclas para la tecla Alt Gr se volverán a asignar.
Las nuevas combinaciones son las siguientes:
AltGr + Q = @
AltGr + 3 = #
AltGr + 5 = ¤
AltGr + 8 = [
AltGr + 9 = ]
AltGr + 7 = {
AltGr + 0 = }
AltGr + + = ~
Los bucles
En muchas situaciones, es necesario repetir la misma operación sobre distintos datos y, para ello, nos pueden ayudar los bucles. Existen distintos tipos de bucle: aquí estudiaremos el bucle for con índice. También veremos cómo utilizar la consola del navegador para el análisis del código.
Temas tratados
•Bucle for
con índice
•Seleccionar elementos en el DOM (HTML) con los selectores CSS
•Modificar atributos de elementos en el DOM
•Utilizar el operador de asignación compuesta
•Utilizar el operador de autoincremento
•Utilizar la consola del navegador
Empezamos con un caso sencillo sobre el cual trabajaremos utilizando bucles.
Nuestro objetivo es contabilizar los elementos de una lista.
<body><ul id="numeros"><li>uno</li><li>dos</li><li>tres</li></ul><p id="output"></p><script type="text/Javascript"> const listaLI = document.querySelectorAll('#numeros li'); const mensaje = `Hay ${listaLI.length} elementos en la lista UL "numeros"`; document.getElementById('output').innerHTML = mensaje;</script></body>
Puedes encontrar este ejemplo en el archivo bucle1 .html
La parte HTML de este archivo contiene una lista no numerada (etiqueta <UL>
) de elementos (etiqueta <LI>
). El elenco tiene un ID asociado con valor "
numeros
"
.
La primera operación que debemos llevar a cabo en nuestro código consiste en localizar esta lista dentro de la página HTML. Para ello, utilizaremos las funciones del DOM (Document Object Model) que ya hemos utilizado en los capítulos anteriores mediante el objeto document
.
Recordemos que, para encontrar un elemento HTML (una etiqueta), se pueden utilizar diferentes opciones (en el capítulo dedicado al DOM retomaremos este argumento):
•Selector CSS .miClase:
busca los elementos que tienen la clase CSS denominada miClase.
•Selector CSS #miId
: busca los elementos que tienen un atributo id
igual a “miId”;
•tag:
busca los elementos de tipo etiqueta (p
, pre
, ul
...).
En nuestro caso específico, podemos localizar los elementos LI
contenidos en el elemento UL
con id=
"numeros
" con el selector CSS "#numeros li
” utilizado como argumento de la función querySelectorAll()
del objeto
document
. La función devuelve una lista de los objetos del documento que corresponden a los selectores especificados como argumentos.
const listaLI = document.querySelectorAll('#numeros li');
El objeto listaLI
(de tipo NodeList
, un contenedor de objetos del cual hablaremos más adelante en este libro) contiene todos los elementos localizados con el selector pasado a la función
querySelectorAll
del objeto document
.
NOTA | Es muy habitual buscar elementos en la página mediante librerías JavaScript, entre las cuales la más famosa es jQuery, puesto que inicialmente esta operación, realizada directamente en JavaScript, era un poco compleja. Sin embargo, con el paso de los años, los navegadores han introducido nuevas funcionalidades (como, precisamente, nuestra función querySelectorAll ), que en muchos casos hacen que adoptar una librería externa no valga en absoluto la pena. |
A continuación, podemos utilizar listaLI
para mostrar cuántos elementos hay en la lista (tres, en nuestro caso) recurriendo a la propiedad length
del objeto listaLI
, que precisamente contiene el número de elementos que contiene el objeto.
const mensaje = `Hay ${listaLI.length} elementos en la lista UL "numeros"`;document.getElementById('output').innerHTML = mensaje`;
Ahora, vamos a tratar de complicar un poco nuestro ejemplo. En lugar de limitarnos a contabilizar cuántos son los elementos de la lista, también queremos asociar a los elementos LI
de esta lista un atributo “value
”, cuyo valor expresa el número en cifras.
En otras palabras, queremos obtener un resultado como el que ves a continuación:
<ul id="numeros"><li value="1">uno</li><li value="2">dos</li><li value="3">tres</li></ul>
NOTA | Naturalmente, debemos pensar que tenemos que realizar esta operación de manera dinámica, por ejemplo, porque no podemos modificar nosotros el archivo HTML (creado por otro desarrollador) o porque la misma lista UL ha sido creada dinámicamente. |
NOTA | Para no complicar demasiado el ejercicio, supongamos que los elementos LI están definidos por orden (“uno”, “dos”...) y que, por tanto, no necesitamos saber que la palabra “dos” indica el número 2, sino que asumiremos simplemente que el primer elemento es 1, el segundo es 2, etc. |
Esto significa que debemos repetir la operación de agregar los atributos value
varias veces, una para cada elemento de la lista. Para ejecutar estas operaciones, recurrimos a uno de los muchos bucles que JavaScript pone a nuestra disposición: el bucle for
con índice.
Su forma es la siguiente:
for (valor índice inicial; valor máximo del índice; cuánto aumenta el índice) {instrucciones a repetir}
Por ejemplo, el bucle:
for (let i=1; i <= 10; i+=1) {instruccion(i); }
repite la instrucción 10 veces, con la variable índice i
, que asume valores del 1 (i=1
) al 10 (i <= 10
), con paso 1 (i += 1
): 1, 2, 3 hasta 10. Cuando i
llega a 11, el bucle termina y la ejecución continúa desde la línea siguiente.
NOTA | Es habitual asignar un nombre corto, como i , j , k , a las variables índice de los bucles. |
En nuestro ejemplo, hemos utilizado el operador de asignación compuesta, que combina un operador aritmético (+, en este caso) con el operador de asignación (=).
Con este operador, conseguimos realizar rápidamente 5 de i
, añade 1 y asigna el resultado a i
”.
La notación:
i+=1
corresponde a:
i = i+1
El operador de asignación compuesta proporciona una solución más sintética y con menos probabilidades de error, dado que no se debe repetir el nombre de la variable sobre la que se trabaja.
Una alternativa a este operador es el operador de autoincremento (i++
), que desarrolla la misma función.
La diferencia principal entre el operador de asignación compuesta (i+=1
) y el operador de autoincremento (i++
)
consiste en el hecho que el primero permite incrementos de distintas unidades (i+=2
, por ejemplo), mientras que el segundo permite solo incrementos de una unidad.
Volviendo a nuestro problema, podemos añadir al código mostrado anteriormente el bucle siguiente:
for (let i=0; i < listaLI.length; i+=1) {listaLI.item(i).value = i+1;}
Puedes encontrar este ejemplo en el archivo bucles2 .html
Analicemos con detalle este código.
El bucle empieza por el número 0 y acaba antes del 3 (el valor de listaLI.length
), es decir, el bucle se ejecuta 3 veces (cuando i=0, cuando i=1 y cuando i=2) y se interrumpe cuando i=3 (i < listaLI.length
).
La instrucción contenida en el bucle for
(es decir, que se repite en cada iteración del bucle):
listaLI.item(i).value = i+1;
utiliza el conjunto de valores item
que representa el conjunto de elementos LI
que se encuentran en nuestra lista UL
.
Cada elemento (es decir, cada elemento LI
) tiene una posición determinada en el conjunto. Podemos acceder a un elemento en concreto indicando entre los paréntesis de item
un número que representa su posición.
En la primera ejecución del bucle, accedo al elemento en la posición 0 (i
al inicio vale 0), en la segunda repetición, accedo al elemento en la posición 1 (i
ha aumentado una unidad), en la tercera y última, accedo al elemento en la posición 2 (i
ha aumentado otra unidad).
En nuestro caso específico:
•En la primera vuelta del bucle for
, i = 0
y listaLI.item(i)
indica el elemento LI
“uno”.
•En la vuelta siguiente, i = 1
y listaLI.item(i)
indica el elemento LI
“dos”.
•En la tercera y última vuelta, i = 2
y listaLI.item(i)
indica el elemento LI
“tres”.
Observa que en JavaScript los conjuntos de valores (como listaLI
) siempre tienen índices que empiezan desde 0: el primer elemento tiene índice (posición) 0, el segundo tiene índice 1 y así sucesivamente.
Ahora que ya hemos visto cómo acceder a los distintos elementos LI
, debemos precisar que con listaLI.item(i).value
accedemos al atributo value
del elemento LI
: si el atributo value
ya no existe, se crea y se le asigna un valor, si no, solo se modifica el valor.
Con la instrucción listaLI.item(i).value = i+1
fijamos el valor de value
al valor del índice aumentado en una unidad (para compensar el hecho de que el índice empieza desde 0 mientras que los números de la lista lo hacen desde 1).
Seguramente has observado que, en este caso, hemos escrito i + 1
y no i+=1
o i+.
Esto es así porque no estamos modificando el valor de i
, sino que solo lo estamos utilizando (leyendo) y, de hecho, es la instrucción for
la que se ocupa de gestionar el incremento de la variable índice en cada vuelta o bucle.
La consola
Sin embargo, si ejecutamos en el navegador este código, no percibimos su acción (estamos actuando a nivel de código HTML con una modificación que no tiene ningún impacto sobre el output de la página en el navegador).
¿Y cómo podemos ver el resultado de nuestro bucle for
?
Una posibilidad consiste en leer el código fuente de la página del navegador. Para acceder al código fuente de la página, pulsa con el botón derecho del ratón en cualquier punto de la página y selecciona la opción “Ver código fuente” o similar (depende del navegador): ¡verás que el código HTML ha sido modificado por nuestro código JavaScript!
Una manera más potente de analizar una página es abrir el modo de desarrolladores pulsando la tecla F12 del teclado (en Firefox y Chrome, también mediante la combinación CTRL+MAYÚS+i).
En función del navegador que se utilice, aparece una ventana independiente o una sección en la página que muestra distintas pestañas, una de las cuales permite analizar el código HTML (Figura 5.1), además de los estilos CSS y el código JavaScript cargados por la página.
Figura 5.1 – El código HTML que genera la página mostrada.
Otra sección muy interesante de las herramientas para los desarrolladores es la consola: un área donde el navegador muestra eventuales errores encontrados durante la carga de la página y/o la ejecución del código JavaScript.
Desde nuestro código, es posible utilizar la consola del navegador para escribir mensajes que nos pueden ayudar a identificar problemas (los denominados mensajes de depuración).
Por ejemplo, podemos modificar nuestro bucle for
del siguiente modo.
for (let i=0; i<listaLI.length; i+=1) {console.log(`i=${i} value=${i + 1} elemento=${listaLI.item(i)}`);listaLI.item(i).value = i+1;}
Puedes encontrar este ejemplo en el archivo Bucles2 .html
La instrucción console.log
llama a la función
log
del objeto console
, que escribe un mensaje en la consola del navegador.
NOTA | Obviamente, si la consola no está abierta, el mensaje no aparece. |
Si ejecutamos el bucle, tendremos, en la consola (Figura 5.2), líneas como estas:
i=0 value=1 elemento=[object HTMLLIElement]
i=1 value=2 elemento=[object HTMLLIElement]
i=2 value=3 elemento=[object HTMLLIElement]
Figura 5.2 – Mensajes en la consola.
Estos mensajes confirman los valores de la variable índice i
, del valor calculado para el atributo value
y del hecho que listaLI.item
contiene objetos JavaScript que representan elementos LI
.
Algunos desarrolladores suelen mostrar en pantalla estos mensajes mediante ventanas alert
que se abren en la página del navegador (Figura 5.3).
alert(`i=${i} value=${i + 1} elemento=${listaLI.item(i)}`);
Figura 5.3 – La ventana alert.
Es preferible utilizar console.log
en lugar de las ventanas de alert
, porque console.log
no interrumpe la ejecución del código y en cambio alert
, sí.
Funciones
En este capítulo hablaremos de funciones que permiten agrupar varias líneas de código para mantener el orden y reutilizar más fácilmente partes de código.
Temas tratados
•Definir y utilizar funciones
•Utilizar el operador ternario
•Pasar parámetros
•Arrays
•Funciones anónimas
•Área de validez de constantes y variables
Una función es un grupo de instrucciones que ejecuta una tarea o calcula un valor.
Para trabajar con funciones se precisan dos pasos:
•declarar la función y definir sus acciones
•llamar a la función en uno o varios puntos del código
Para explicar mejor el uso de funciones, empezaremos con un ejemplo:
<body><p id="output"></p><img id="carita" /><script type="text/javascript">function esFinDeSemana() {const dia = new Date().getDay();if (dia === 0 || dia === 6) return true;else return false}let valorSrc;if (esFinDeSemana() === true) valorSrc = 'CaritaFeliz.png';else valorSrc = 'CaritaTriste.png';document.getElementById('carita').src = valorSrc;</script></body>
Puedes encontrar este ejemplo en el archivo Funciones .html
Empezamos el análisis de este código precisamente por la función esFinDeSemana
:
function esFinDeSemana() {const dia = new Date().getDay();if (dia === 0 || dia === 6) return true;else return false}
Observa que, para crear la función, se utiliza la palabra function
seguida del nombre de la misma función y, a su vez, seguida de un par de paréntesis.
Todas las líneas de código que forman parte de la función se sitúan entre llaves.
Anteriormente hemos dicho que una función puede limitarse a ejecutar acciones, o bien puede devolver un valor, como la función que estamos analizando.
El valor devuelto se introduce con la palabra return
.
La función utiliza un código que ya te debería ser familiar: tras haber leído el número del día de la semana, si es sábado (6) o domingo (0), la función devuelve true
y, si no, devuelve false
(es decir, un valor booleano).
En realidad, podríamos escribir la función evitando la instrucción if
y utilizando una notación más resumida:
return dia === 0 || dia === 6;
Esta instrucción devuelve el resultado de la comparación dia
=== 0 || dia === 6
, es decir, verdadero o falso, igual que la instrucción if
que hemos escrito inicialmente.
Tanto si utilizamos una instrucción if
, como si recurrimos a la forma más resumida, el valor que devuelve la función se utilizará posteriormente en una instrucción if
para crear el nombre de la imagen que se desea cargar en el objeto <img>
con el id = carita.
if (esFinDeSemana() === true) valorSrc = ‘CaritaFeliz.png’;else valorSrc = ‘CaritaTriste.png’;
Observa que el nombre de la función se debe llamar completo entre paréntesis.
En este ejemplo, para simplificar un poco la lectura, hemos ejecutado explícitamente la comparación esFinDeSemana() === true
; sin embargo, normalmente, cuando la parte derecha de la comparación es un valor booleano, no se ejecuta la comparación de manera explícita, sino que basta con una notación más reducida:
if (esFinDeSemana()) valorSrc = 'CaritaFeliz.png';
Antes de continuar, queremos mostrarte un modo más sintético de escribir una instrucción if
, una manera que se puede utilizar cuando se tiene una comparación booleana y, por tanto, una única expresión a valorar si la comparación es verdadera y una única expresión a valorar si es falsa.
Las expresiones en cuestión no pueden llevar a cabo una operación, solo devolver un valor.
Toda la instrucción if
anterior puede ser escrita del modo siguiente:
const valorSrc = esFinDeSemana() ? 'CaritaFeliz.png' : 'CaritaTriste.png';
Esta notación se denomina habitualmente operador ternario porque se compone de tres partes:
test booleano ? valor si verdadero : valor si falso
El resultado de un operador ternario, que siempre es un valor, se asigna a una variable o a una constante (o se utiliza para ejecutar operaciones que todavía no hemos explicado), si no, se pierde. Nuestra función se utiliza una sola vez, pero nada nos impide utilizarla también en otras situaciones.
Por ejemplo, podríamos enriquecer nuestro código como se indica a continuación, para mostrar, además de una imagen, también un mensaje adecuado para el momento de la semana:
const valorSrc = esFinDeSemana() ? 'CaritaFeliz.png' : 'CaritaTriste.png';const mensaje = esFinDeSemana() ? 'Diviértete' : 'Venga, que ya falta poco';document.getElementById('carita').src = valorSrc;document.getElementById('output').innerHTML = mensaje;
Puedes encontrar este ejemplo en el archivo Funciones1 .html
Tratemos de complicar un poco nuestro ejemplo de uso de una función haciendo que nos muestre el nombre del día de la semana actual.
<script type="text/javascript">const dia = new Date().getDay();function esFinDeSemana() {return dia === 0 || dia === 6;}function queDia() {const nombreDia = ['Domingo', 'Lunes', 'Martes', 'Miércoles', 'Jueves', 'Viernes', 'Sábado'];return nombreDia[dia];}const valorSrc = esFinDeSemana() ? ‘CaritaFeliz.png’ : ‘CaritaTriste.png’;document.getElementById('carita').src = valorSrc;document.getElementById('output').innerHTML = queDia();</script>
Puedes encontrar este ejemplo en el archivo FuncionesArray .html
La auténtica novedad de este código es la línea:
const nombreDia = ['Domingo', 'Lunes', 'Martes', 'Miércoles', 'Jueves', 'Viernes', 'Sábado'];
La constante nombreDia
, a diferencia de las que hemos visto hasta hora, contiene un conjunto de datos.
Se define como array y contiene múltiples valores ordenados y colocados entre corchetes.
Dado que los valores de un array están dispuestos en un orden determinado, es posible acceder a él especificando su posición mediante un número de índice que empieza desde 0 (el primer elemento del array tiene el valor 0).
Para acceder a un elemento de un array, basta con poner entre los corchetes de dicho array el número de índice del elemento.
nombreDia[2]
devolverá el valor “Martes” que se encuentra en la posición 2 en el array (0 corresponde a domingo; 1, a lunes; 2, a martes... y 6, a sábado).
Nuestro array contiene los nombres de los días de manera que su posición corresponda al valor devuelto por getDay()
y almacenado en la variable dia
, que después podemos utilizar como índice de nuestro array.
nombreDia[dia]