1 of 67

Javascript#2

Segunda parte

2 of 67

VAMOS A IR APRENDIENDO LOS CONCEPTOS SIGUIENDO VARIOS EJEMPLOS

3 of 67

Piedra, papel o tijera

4 of 67

Problema

​

Vamos a hacer una app para jugar contra la “computadora” al piedra, papel o tijera.

​

Creemos un botón, que al apretarlo “simule” la inteligencia de una persona y elija automáticamente una de las tres opciones.

5 of 67

Resolver el problema

¿Qué vamos a aprender?

  • Qué son los arreglos
  • Para que se usan los arreglos
  • Declarar un arreglo
  • Mostrar un elemento del arreglo

6 of 67

¿Cómo vamos a “simular” que la computadora elija una de las tres opciones disponibles?

​

La idea es elegir al azar una de las tres opciones del juego:

​

Podríamos generar un número al azar y hacer 3 if (o un switch) para saber que opción elegir.

​

Contra: Si bien tenemos tres opciones puede haber variantes con más opciones. Se hace muy largo el código.

​

Solución: Hagamos un código que elija al azar de una lista de opciones, sean 3 o la cantidad que sean.

5 opciones

7 of 67

Arreglos

VARIABLE SIMPLES

ARREGLO

Los arreglos almacenan elementos en una colección de datos ordenados.

​

​

Son una variable que tiene muchas posiciones.

​

​

En lugar de una caja, ahora tenemos una cajonera.

“Juan”

nombre

8 of 67

Declarar arreglos

​

// declarar un arreglo vacío

let names = [];

​

​

​

​

// declarar arreglo con tres elementos

let cars = ["Saab", "Volvo", "BMW"];

​

names

"Saab"

"Volvo"

"BMW"

cars

no tiene posiciones

tiene 3 posiciones (0, 1, 2)

0

1

2

9 of 67

Arreglos - Acceso

Acceder a un arreglo

Los elementos se acceden por índice (comienzan en 0).

​

let cars = ["Saab", "Volvo", "BMW"];

let car = cars[0];

//cars es un arreglo, car es un texto

​

console.log(car); // “Saab”

console.log(cars[1]); // “Volvo”

console.log(cars[2]); // “BWM”

"Saab"

"Saab"

"Volvo"

"BMW"

car

cars

0

1

2

10 of 67

Tamaño de un arreglo

let frutas = ["manzana", "pera", "naranja"];��Cantidad de elementos�frutas.length; // 3�

​

11 of 67

Resolviendo el problema

Creo un arreglo para almacenar la lista de opciones que tiene la computadora para elegir.

​

let opciones = [“piedra”, “papel”, “tijera”];

​

Ejecutó un numero random entre 0 y 2 para elegir al “azar” una de las opciones.

12 of 67

Random

  • Podemos utilizar también la función matemática

​

Math.floor();

​

Que redondea al menor entero

​

Math.floor((Math.random() * 6) + 1);

​

0 < Math.random() * 6 < 5.999

​

​

​

​

​

​

​

​

​

​

En este caso tenemos 3 opciones, o mejor aún opciones.length opciones

REPASO

Como los arreglos empiezan en 0 no hace falta sumar 1

13 of 67

Solución

"use strict"

​

let btn = document.querySelector('#btn-play');

btn.addEventListener('click', jugar);

​

// arreglo con todas las opciones posibles

let opciones = ['piedra', 'papel', 'tijera'];

​

function jugar() {

// numero random entre 0 y el tamaño del arreglo

let random = Math.floor((Math.random() * opciones.length));

let opcion = opciones[random];

// escribimos el resultado en el html

document.querySelector('.result').innerHTML = opcion;

}

​

14 of 67

Resumen

Aprendimos

  • Arreglos
  • Acceder al arreglo

​

15 of 67

Aplicación de sorteos

16 of 67

Problema

El piedra/papel/tijera fue un éxito. Así que nos contrataron para hacer otra app.

Tenemos que hacer una app para hacer sorteos donde podamos agregar todas las personas que queramos y nos de un ganador.

Creemos un formulario y una lista vacía para ir completando con lo que carga el usuario. Además tiene que tener un botón de reset.

17 of 67

Resolver el problema

¿Qué vamos a aprender?

  • Recorrer un arreglo
  • Agregar elementos a un arreglo
  • Vaciar un arreglo

​

18 of 67

Modelo vs Vista

¿Por qué necesito un arreglo si puedo ir insertando los nombres directo en el HTML?

​

  • Usar el DOM para guardar todo:
    • todo es string (no puedo guardar otros tipos)
    • difícil de recorrer para buscar
    • imposible en aplicaciones con muchos datos

​

No es responsabilidad del DOM guardar los datos, sólo mostrarlos!

​

​

19 of 67

Modelo vs Vista

​

Al aumentar la complejidad de mi aplicación, es casi obligatorio guardar el estado de los datos en Javascript, y luego representarlo (dibujarlo/escribirlo) en el DOM.

​

Las variables en Javascript son nuestro “modelo” de datos y después se muestra en el DOM, llamado vista .

​

​

Mati

Franco

Nacho

Javi

Los usuarios a sortear son:

  • Mati
  • Franco
  • Nacho
  • Javi

Arreglo en JS, más fácil de modificar

Lista en el HTML generada desde el arreglo

20 of 67

Agregando elementos y borrando

let frutas = ["manzana", "pera", "naranja"];��Cantidad de elementos�frutas.length;�

Agregar un elemento al final�frutas.push("mandarina");��Borrar último elemento

frutas.pop();

​

Vaciar el arreglo

frutas = [];

​

21 of 67

Recorriendo Arreglos

let arr = [1,2,3]

​

// foreach de ES6�for (let elem of arr) { // 1, 2, 3� console.log(elem);�}

​

// método clásico�for (let i=0; i<arr.length; i++) { // 1, 2, 3� let elem = arr[i];� console.log(elem);

}

​

​

​

​

​

22 of 67

Resolviendo el problema

Creo un arreglo para almacenar la lista de personas que ingresa el usuario.

“Mati”

“Franco”

“Nacho”

“Javi”

“Otro nombre”

let personas = [];

0

1

2

3

4

5

23 of 67

Resolviendo el problema

​

Creo 3 botones (Agregar, Limpiar todos, Borrar ultimo), 1 input para agregar nombres

​

Creo funciones agregar(), reset(), borrarUltimo() y mostrar()

Llamo a mostrar cada vez que se modifica el arreglo.

​

​

​

24 of 67

Solución

function sortear() {

let pos = Math.floor(

Math.random()*nombres.length);

let g = document.querySelector("#ganador");

g.innerHTML = nombres[pos];

}

let nombres = [];

​

function agregar() {

let nombre = document.getElementById("nombre").value;

nombres.push(nombre);

mostrar();

}

​

function reset() {

nombres = [];

mostrar();

}

​

function mostrar() {

let lista = document.querySelector("#listado");

lista.innerHTML = ""; //borro todo lo que haya

for(let n of nombres){

lista.innerHTML += `<li>${n}</li>`;

//lista.innerHTML = lista.innerHTML + "<li>" + n + "</li>";

}

} //...los event listener

​

function borrarUltimo() {

nombres.pop();

mostrar();

}

variable global para el estado (el modelo)

una función por evento

una función para evitar duplicar código en cada evento

generamos HTML desde JS

el sorteo es igual

25 of 67

Resumen

Aprendimos

  • Manipulaciones sencillas sobre arreglos (agregar, vaciar)
  • Recorrer arreglos

26 of 67

Variables globales y DOMContentLoaded

27 of 67

Variables Globales

Como la variable contador es global, se puede acceder desde cualquier lado de la aplicación. Incluso se puede ver o modificar desde la consola del navegador!

​

​

​

​

​

Esto no es bueno, incluso dos programas JS podrían usar el mismo nombre de variable y entonces la compartirán sin saberlo.

console.log(contador);

contador = contador + 1000;

console.log(contador);

28 of 67

Evitar variables y funciones globales

  • En lugar de declarar las variables y funciones como globales podemos incluirlas en un objeto para aislarlas.
  • Crear un ámbito de todo el documento de JS para que las variables no estén disponibles desde fuera de él.
  • Esa función la ejecutamos cuando el DOM se haya cargado

29 of 67

Otra forma de hacerlo

Podemos configurar todos los eventos una vez que ya se cargo el DOM. De este modo nos aseguramos que estén cargados todos los elementos del DOM antes de manipularlos

​

​

document.addEventListener("DOMContentLoaded",

iniciarPagina);

​

function iniciarPagina(){

// código de inicialización de eventos

}

30 of 67

Evitar variables y funciones globales

document.addEventListener('DOMContentLoaded', iniciarContador);

​

function iniciarContador() {

"use strict";

let btn = document.getElementById("btn-click");

btn.addEventListener("click", sumar);

​

let contador = 0;

​

function sumar() {

//incrementa el valor de contador

contador++;

//es lo mismo que contador = contador + 1

let valor = document.getElementById("spanContador");

valor.innerHTML = contador;

}

}

leo variables de afuera, no de más adentro

“contador” no puede usarse desde más afuera

31 of 67

32 of 67

Resumen

Aprendimos a

  • Usar variables globales para recordar cosas
  • Limitar desde donde son accesibles esas variables
    • DOMContentLoaded

33 of 67

App Contador de Pasos

34 of 67

Contador de pasos

Queremos realizar una app que lleve la cuenta de la cantidad de pasos que realizo por día:

​

  • En la página web se muestra la cantidad de pasos en el día.
  • Hay un botón para incrementar la cantidad de pasos
  • Hay un botón para decrementar la cantidad de pasos
  • Hay un input de texto para sumar muchas pasos en una sola acción

​

35 of 67

¿Qué vamos a aprender?

​

  • tipos de variables
    • Al escribir el texto, voy a tener un texto y lo quiero sumar como número.

​

  • funciones anónimas
  • parámetros en las funciones

​

​

​

​

​

36 of 67

Tipos de Datos

Las variables pueden tener tipos:

​

  • String
  • Number
  • Boolean
  • Null
  • Undefined
  • Object
    • Function
    • Array
    • Date
    • Expresiones Regulares (RegExp)

37 of 67

Tipado de Variables - Tipos

El tipado estático nos obliga a definir desde el principio el tipo de una variable. Lenguajes con tipado estático son C++, Java, C# (casi) entre otros.

​

El tipado dinámico nos da la facilidad de no definir los tipos al declarar una variable, algunos ejemplos son PHP, JavaScript, Grooby, Phyton, entre otros.

​

¿Se les ocurren pros y contras?

​

​

38 of 67

Tipos

Javascript tiene tipos dinámicos.

  • Una misma variable puede cambiar de tipo.
  • Puede causar confusiones (y errores que no encuentro durante horas).

​

let nombre = "Pepe"; //nombre es un string

…

nombre = 2; //nombre es un int (cambia tipo)

Mala práctica

39 of 67

Conversión de tipos

  • Cuidado con los tipos, son dinámicos y no saber de qué tipo es una variable puede cambiar el resultado.

5 == "5" //true

"1" + 2 + 3; //"123"

​

//Conversion manual de tipos�parseInt("1", 10) + 2 + 3; //6

​

  • ES6 introduce una nueva forma de trabajar con Strings

'<p>Vos sos '+nombre+' '+apellido+'.</p>'

​

`<p>Vos sos ${nombre} ${apellido}.</p>`

​

​

40 of 67

Undefined

  • undefined es un tipo fundamental en Javascript
  • Las variables sin inicializar valen undefined
  • Variables y miembros sin declarar valen undefined (salvo que uses “use strict” que causa una falla)
  • Las funciones siempre devuelven un valor, si no tienen valor de retorno devuelven undefined

41 of 67

Escribiendo código JavaScript más limpio

​

  • Funciones con parámetros
  • Funciones anónimas

42 of 67

Parámetros

Podemos hacer el código más genérico y reutilizable utilizando parámetros y devolviendo valores.

​

Ejemplo:

// función específica para sumar 2 + 4

function sumarDosMasCuatro {

let suma = 2 + 4;

console.log(suma);

}

​

--------------

// función genérica para sumar dos valores cualquiera

function sumar(parametro1, parametro2) {

return parametro1 + parametro2;

}

​

// la llamamos con los valores que queremos

let resultado = sumar(2, 8); //devuelve 10

console.log(resultado);

​

El primer parámetro va a valer 2, el segundo va a valer 8, por lo que la suma dará 10

​

Los parámetros son la entrada del código, y el valor que devuelve es la salida.

43 of 67

Funciones anónimas

Se usan para no crear tantas funciones que se usan en un solo lugar

  • Es una función sin nombre que se escribe directamente donde quería pasar parámetros.
  • En este caso encapsula a la función que si pasa parámetros.

btn.addEventListener("click", sumar(20,50));

​

​

btn.addEventListener("click", function(){

let valor1 = 20;

let valor2 = 50;

let resultado = sumar(valor1, valor2)

});

​

Declaramos una función anónima, para poder llamar a una función con parámetros

44 of 67

Resolver el problema

<button id="btn-decrementar">-</button>

<button id="btn-incrementar">+</button>

<button id="btn-agregar">AGREGAR</button>

​

​

Asignar eventos a los 3 botones

document.querySelector('#btn-incrementar').addEventListener('click', function(e) {

incrementar(1)

});

​

document.querySelector('#btn-decrementar').addEventListener('click', function(e) {

incrementar(-1);

});

​

document.querySelector('#btn-agregar').addEventListener('click', incrementarManual);

​

​

​

JS + Función anónima:

45 of 67

Resumen

Aprendimos

  • Tipos
  • Conversiones de tipos
  • Funciones anónimas
  • Funciones con parámetros

46 of 67

Reloj

47 of 67

Reloj - Bomba

Simular la cuenta regresiva de una bomba.

Con un botón activarla y dejar 5 segundos para escapar y comenzar la cuenta regresiva.

El valor de la cuenta regresiva se ingresa por un input

48 of 67

Qué vamos a aprender

Qué vamos a aprender?

  • Ejecutar eventos diferidos en tiempo, o retardados
  • Ejecutar eventos que se repiten en intervalos de tiempo hasta que hagamos un reset.

​

​

​

​

​

49 of 67

Eventos de tiempo

Se puede programar un evento, para ejecutar una función dentro de M milisegundos.

​

//dispara (ejecuta bang) en 5 segundos

let timer = setTimeout(bang, 5000);

​

​

​

​

​

50 of 67

Eventos de tiempo

let timer = setInterval(clock, 1000);

…

clearInterval(timer);

​

setInterval llama a la función cada 1000 milisegundos, hasta que se limpie el intervalo.

​

51 of 67

Resultado

Cuenta Regresiva

​

function cuentaRegre(){� let intervalo = setInterval(function() {� if (i === 0) {� clearInterval(intervalo); // limpio intervalo� alert('BOOOOOM!!');� }� else {� i--;� }� }, 1000);�}

​

​

https://codepen.io/webUnicen/pen/Peojzb

52 of 67

Implicancias de eventos de tiempo

[TBC]

53 of 67

Resumen

Aprendimos

  • Usar temporizadores e intervals

54 of 67

Javascript - Buenas prácticas

55 of 67

Separar los "event handlers"

// Mal hecho

function handleClick(event){

let popup = document.getElementById("popup");

popup.style.left = event.clientX + "px";

popup.style.top = event.clientY + "px";

popup.className = "reveal";

}

// Mejor, pero sigue estando mal

function handleClick(event){

showPopup(event);

}

function showPopup(event){

let popup = document.getElementById("popup");

popup.style.left = event.clientX + "px";

popup.style.top = event.clientY + "px";

popup.className = "reveal";

}

// La solucion correcta

function handleClick(event){

showPopup(event.clientX, event.clientY);

}

function showPopup(x, y){

let popup = document.getElementById("popup");

popup.style.left = x + "px";

popup.style.top = y + "px";

popup.className = "reveal";

}

56 of 67

Usar Cache de Selectores

​

Las consultas al DOM son MUY lentas.

Editarlo también.

​

57 of 67

Usar Cache de Selectores

  • Salvar los resultados de selectores optimizan mucho el código.

​

function sinCache () {

let i, val;

for(i=0; i<50; i++){

val = document.getElementById('title').innerHTML

}

}

function conCache (){

let i, val;

let h1 = document.getElementById('title');

for(i=0; i<50; i++){

val = h1.innerHTML;

}

}

58 of 67

JS y sus detalles

59 of 67

Obtener nodos del DOM

  • Se pueden obtener elementos del DOM consultando por un ID, nombre, clase o un selector.
  • Podemos obtener como resultado de uno o múltiples elementos del DOM

Retorna un nodo

let elem = document.getElementById("identificador");

let singleElem = document.querySelector(".myclass");

​

Retorna uno o más

let manyElements = document.getElementsByClassName("myclass");�let manyElems = document.querySelectorAll(".myclass");

​

Más info https://developer.mozilla.org/en-US/docs/Web/API/Document/querySelector

​

sin el punto

Selector de CSS

60 of 67

Comparaciones cortas en JS

?

  • If más corto:

let tmp = (bool) ? 1 : 2

​

es igual que

let tmp = 0;

if(bool)

tmp=1;

else

tmp=2;

  • Solo sirve cuando es un valor que se asigna en la misma variable en las dos ramas.

​

​

​

61 of 67

Falsey evaluation

En Javascript, hay diferentes cosas que al convertirla a bool, se transforma a false automáticamente.

null == undefined == 0 == false == ""

No es tan así, pero es una buena simplificación.

let a = null; let b; //undefined

let c = 0; let d = false;

let e = "";

if (a), if (b), if (c), if (d), if (e) //false

Puedo pasarme horas revisando un bug en una comparación, que era por un undefined en la variable.

62 of 67

Falsey Evaluation

  • Por costumbres de otros lenguajes, es normal escribir condicionales tipo C
  • Los condicionales JS son más cortos y eficientes

63 of 67

Largo de una cadena

Existen muchas funciones que ya trae Javascript

​

Para calcular el largo de una cadena puedo usar:

​

let largo = str.length("cadena");

El valor calculado se devuelve y debe guardarse en una variable

64 of 67

Ejercicios

65 of 67

Ejercicios

Ejercicio #1

  • Utilizando lo visto en esta clase, crear una función Javascript que oculte y muestre un div que contiene información.
  • Analizar cómo modificar el ejercicio para que sea un código reutilizable (poder poner muchos botones que oculten o muestren un div respectivo)

​

Ejercicio #2

  • Tengo una lista de tareas, y quiero dinámicamente (sin refrescar la página) agregar tareas.

​

​

66 of 67

AHORA LES TOCA PRACTICAR :D

67 of 67

Más Información

Libros

Eventos

O'Reilly “You don’t know JS, ES6 and beyond”

https://github.com/getify/You-Dont-Know-JS/tree/master/es6%20%26%20beyond