Herramientas de usuario

Herramientas del sitio


informatica:programacion:cursos:programacion_avanzada_javascript

Programación avanzada con JavaScript y ECMAScript

Notas del curso Programación avanzada con JavaScript y ECMAScript del Clúster Tic de Galicia.

  • Horas: 60
  • Fecha Inicio: 01/10/2024
  • Fecha Fin: 10/12/2024

Objetivos

JavaScript es un lenguaje que engaña mucho. Lo básico es muy sencillo y se aprende rápido, pero después presenta gran cantidad de complicaciones. Hay quien llega a odiarlo y le parece un mal lenguaje, pero muchas veces es simplemente porque no se conoce a fondo y no se entiende bien su funcionamiento.

En este completo curso de más de 300 lecciones, dominarás hasta el último detalle de JavaScript, incluyendo las características más recientes del lenguaje. Con él te convertirás sin duda en un mejor profesional de la web. Aprenderás, entre otras muchas cosas:

  • Peligros con el ámbito de las variables, shadowing y hoisting.
  • Técnicas eficientes de programación orientada a objetos con JavaScript: constructores, prototipos, herencia, encapsulación, polimorfismo, espacios de nombre, interfaces…
  • Clausuras y otros conceptos importantes.
  • Controlando el valor de contexto.
  • Reflexión e introspección.
  • Trabajo con el DOM: jerarquías, recursión, colecciones “vivas” y “estáticas”, localización de elementos, modificación dinámica multi-navegador…
  • Manejo avanzado de eventos en páginas web: gestión unificada y multi-navegador.
  • Creación de eventos personalizados propios.
  • Subclasificación.
  • Trabajo avanzado con funciones.
  • Funciones anónimas.
  • Modularización y organización de código con módulos ECMAScript.
  • Optimización de carga de scripts.
  • JSON, JSONP, CORS.
  • El modo estricto de JavaScript.
  • Uso práctico de la consola y sus comandos.
  • Funciones y tipos de datos ECMAScript.
  • Nuevas formas de declarar variables y su efecto en el ámbito, this, etc…
  • Nuevos tipos de colecciones y agrupamientos de información.
  • Promesas.
  • Operador flecha, pérdida de this, uso de lambdas.
  • El API fetch para peticiones asíncronas.
  • Creación y uso de funciones asíncronas con async/await.
  • Mejoras y cambios en definición y notación de objetos.
  • Uso de literales de cadena y plantillas.
  • Símbolos y sus aplicaciones avanzadas.
  • Weakmaps.
  • Desestructuración de datos y el operador “spread”.
  • Iteradores y generadores.
  • Programación orientada a objetos en ECMAScript.
  • Creación y uso de proxies.

Temario

Introducción

JavaScript es un lenguaje que engaña mucho. Lo básico es muy sencillo y se aprende rápido, pero después presenta gran cantidad de complicaciones. Hay quién llega a odiarlo y le parece un mal lenguaje, pero en muchos casos es debido a que no se conoce a fondo y no se entiende bien su funcionamiento.

Por otro lado, muchos de los usuarios habituales de bibliotecas como jQuery y similares saben utilizarlas pero desconocen las bases sobre las que se sustentan. Por ello, cuando aparece un error o pasan cosas “extrañas” carecen de los conocimientos necesarios para diagnosticar y solucionar el problema.

Para programar a un nivel profesional con JavaScript es indispensable tener ciertos conceptos clave muy claros, o acabaremos con programas llenos de problemas, difíciles de mantener, que interfieren con las bibliotecas de otros, y que no funcionan bien en todos los navegadores.

En esta primera parte del curso vamos a meternos a fondo en JavaScript (ECMAScript 5).

Es probable que algunas de las cuestiones que se comentan ya las conozcas, pero en cualquier caso te vendrá bien repasarlas y seguro que hay detalles que desconocías o no tenías claros. Y como se suele decir, “El demonio está en los detalles”, y son precisamente éstos los que a veces marcan la diferencia entre un buen código y uno del montón o en comprender bien por qué falla un determinado código o por qué se comporta de manera “extraña”.

A través de 9 completos módulos y más de 150 detalladas lecciones, en esta parte del curso aprenderás entre otras muchas cosas:

  • Peligros con el ámbito de las variables, shadowing y hoisting
  • Cuestiones avanzadas para trabajo con matrices
  • Cuestiones avanzadas con Fechas
  • Problemas con temporizadores y cronómetros
  • Depuración de JavaScript
  • El modo estricto de JavaScript
  • Las herramientas del desarrollador de Chrome
  • Uso práctico de la consola y sus comandos
  • Puntos de interrupción: normales, condicionales, logpoints
  • Técnicas eficientes de programación orientada a objetos con JavaScript: constructores, prototipos, herencia, encapsulación, polimorfismo, espacios de nombre, interfaces…
  • Clausuras y otros conceptos importantes
  • Los peligros de “this”
  • Controlando el valor de contexto
  • Reflexión e introspección
  • Sobrecarga de funciones y métodos
  • Parámetros opcionales
  • Trabajo con el DOM: jerarquías, recursividad, colecciones “vivas” y “estáticas”, localización de elementos, modificación dinámica multinavegador…
  • Manejo avanzado de eventos en páginas web: gestión unificada y multinavegador
  • Subclasificación
  • Creación desde cero de una biblioteca de validación avanzada de formularios no-intrusiva.
  • Trabajo avanzado con funciones
  • Funciones anónimas
  • El patrón módulo
  • AJAX con JavaScript puro: técnicas fundamentales, principales problemas y cómo solucionarlos…
  • Optimización de carga de scripts
  • JSON, JSONP, CORS

Evaluaciones

Conceptos fundamentales avanzados de JavaScript

¿Cómo podrías conseguir que un código se ejecutase a intervalos regulares de tiempo, entre ejecuciones completas, con toda certeza y sin que se pierdan o se retrasen ejecuciones, incluso aunque estos intervalos fuesen cortos y el proceso largo?

  • Simplemente usando setInterval, que está diseñado para eso
  • Utilizando setTimeout y estableciendo un nuevo setTimeout al final del código que se ejecuta (Correcto)
  • No es posible conseguir esto en casos extremos debido a que JavaScript se ejecuta siempre en un solo hilo y no tiene paralelismo

¿Es posible controlar mediante código el valor que toma la palabra clave this dentro de una función?

  • No, se establece automáticamente según desde donde se esté llamando
  • Sí, utilizando las funciones call y apply
  • Sí, utilizando la función setContext
  • Sí, guardándola en una variable (por ejemplo “that”) gracias a las clausuras

¿De qué maneras puedes definir una nueva fecha válida en JavaScript y obtener el resultado esperado según sus parámetros? Es decir, todas estas opciones devuelven una fecha porque JavaScript es muy laxo con todos los tipos, pero no todas devuelven la fecha esperada (marca todas las correctas).

  • new Date(); (Correcto)
  • new Date(“mes día, año horas:minutos:segundos”); (Correcto)
  • new Date(“dd/mm/yyy hh:mm:ss”);
  • new Date(dia, mes, año);
  • new Date(año, mes, dia); (Correcto)

¿Qué obtendríamos en la variable res al final de este código?:

var n1 = 1;
var n2 = "1";
var res = (n1 === n2);
  • true
  • false (Correcto)

Cuando llamas al método sort de una matriz ¿qué efecto tiene éste sobre la misma?

  • Ninguno: devuelve como resultado la matriz ordenada, pero no afecta a la original en absoluto.
  • Cambia la matriz original para dejarla ordenada. Es un método que no devuelve nada.
  • Cambia la matriz original para dejarla ordenada además de devolverla de nuevo para poder enlazar llamadas con otro métodos. (Correcto).
  • Este método no existe para las matrices.

¿Cuál es el resultado de esta operación?: 3+2+"5"

  • “55” (Correcto)
  • “325”
  • 10
  • 5

¿Cómo se puede conseguir la sobrecarga de funciones en JavaScript (funciones con el mismo nombre pero diferente número de argumentos)? (marcar todas las correctas)

  • Definiendo varias veces la función, cada vez con unos argumentos diferentes
  • Definiendo la función una vez con un número cualquiera de argumentos (incluso ninguno) y luego usando la colección arguments para acceder a los mismos (Correcto)
  • Definiendo la función una vez con un número cualquiera de argumentos (incluso ninguno) y luego usando la colección parameters para acceder a los mismos
  • Creando una función con el número máximo de argumentos que vamos a necesitar, y luego comprobando cuáles se han pasado y cuáles no (typeof != undefined) (Correcto)
  • Usando la palabra clave overrides
  • Usando la palabra clave overloads

¿Para qué sirve la instrucción instanceof?

  • Para crear una nueva instancia de un objeto en JavaScript
  • Para determinar si un objeto es una instancia de una determinada clase (Correcto)
  • Devuelve una cadena de texto con el nombre de la clase del objeto que se le pase como parámetro
  • Hace que un objeto herede de otro

¿Qué hace el siguiente código JavaScript?:

var res = "";
var i = 0;
 
for (;;){
    res += i
    i++;
    if (i>9) break;
}
  • Nada, produce un error de sitnaxis porque está mal definido el bucle for
  • Se genera un bucle infinito y el navegador acaba preguntando si queremos detenerlo
  • Es un bucle determinado que concatena los números del 0 al 9 en una cadena (Correcto)
  • Es un bucle determinado que concatena los números del 0 al 10 en una cadena

¿Para qué sirve la palabra clave with de JavaScript?

  • Esta palabra clave no existe en JavaScript, solamente en C#, VB y Java
  • Permite comprobar si un objeto dispone de una determinada propiedad: objeto.with(“propiedad”) devolviendo true en caso afirmativo
  • Permite utilizar los métodos y propiedades de un objeto dentro de un bloque sin tener que escribir su nombre ni el punto separador, consiguiendo código más compacto y legible, por ejemplo with(miObjeto) { Metodo(); propiedad = 0} (Correcto)
  • Permite crear un alias para un objeto de modo que abreviemos su uso en el código, por ejemplo: with (o=miObjeto) { n.Metodo(); n.propiedad = 0}

Manejo del navegador y AJAX

¿Cuáles son las principales ventajas de usar el BOM para desarrollo web? (marca todas las correctas)

  • Está soportad por todos los navegadores, incluso los más antiguos (Correcto)
  • Está soportado por todos los navegadores modernos, de menos de 5 años, pero no por los antiguos que nadie usa ya
  • Permite el acceso rápido a cualquier elemento de la página con un modelo unificado
  • Permite el acceso rápido a los elementos de los formularios (Correcto)
  • Nos ofrece información sobre el usuario actual, como donde está ubicado o qué zona horaria utiliza
  • Nos ofrece información sobre el navegador y su entorno, como por ejemplo la resolución de pantalla (Correcto)

Cuando tienes una función que está trabajando como manejador de un evento, ¿qué referencia contendrá la variable “this” al utilizarla desde dentro del manejador?

  • Una referencia al objeto global (window)
  • Una referencia al objeto event que representa los datos del evento
  • Una referencia al elemento que ha provocado el evento
  • Una referencia al elemento que está capturando el evento, el cual no tiene que coincidir con el que lo ha provocado (Correcto)

¿De qué manera es posible obtener siempre una referencia al objeto que ha generado el evento en un manejador de eventos siguiendo el modelo del DOM?

  • Usando la propiedad currentTarget del evento
  • Usando el objeto this, que siempre apunta al objeto que ha generado el evento
  • Usando la propiedad target del evento (Correcto)

OJO, estas tres propiedades nos dan esta información cuando se el evento se captura en el elemento que lo ha producido, pero solo target nos da una referencia cuando se captura en un elemento superior o inferior de la jerarquía.

¿Cuál es la propiedad del DOM que nos devuelve una referencia al elemento raíz de la página, es decir, al que representa a la etiqueta del código fuente HTML de la página actual?

  • window.root
  • document.root
  • document.documentElement (Correcto)
  • window.html

¿Cuál de los siguientes métodos de selección de elementos del DOM devuelve una colección estática y no una colección “viva” de elementos?

  • getElementById
  • getElementsByTagName
  • querySelectorAll (Correcto)
  • getElementsByName

ECMAScript fundamental

¿Cuáles son los estados posibles de una promise? (selecciona las correctas)

  • Rechazada (rejected)
  • Completada (fulfilled) (Correcto)
  • Iniciada (Started)
  • Bloqueada (Blocked)
  • Con error (Rejected) (Correcto)
  • Encolada (Queued)
  • Suspendida (Suspended)
  • Pendiente (Pending) (Correcto)

¿Qué diferencia hay entre JSON y la notación de objeto? (Marca todas las correctas) (selecciona las correctas)

  • Ninguna. Son lo mismo.
  • En JSON los nombres de propiedades van entre comillas. En notación de objeto, no (Correcto)
  • En JSON las propiedades pueden ser funciones. En notación de objeto, no
  • En notación de objeto las propiedades pueden ser funciones. En JSON, no (Correcto)
  • En notación de objeto los nombres de propiedades van entre comillas. En JSON, no

El método then… (marca todas las afirmaciones correctas)

  • …se ejecuta en cuanto la promise es completada (Correcto)
  • …se ejecuta SIEMPRE en cuanto la promise entra en estado de error
  • …no existe
  • …espera dos parámetros: una promise y una función
  • …espera una función como parámetro (Correcto)
  • …devuelve un booleano indicando si la promise se ha completado o no
  • …devuelve una promise (Correcto)

Rellena los huecos con las siguientes palabras (sin comillas): “menos”, “Map”, “más”, “objeto literal”, “clave”, “valor” Una de las palabras anteriores es erronea.

  • Usar un Map como una colección clave-valor es menos eficiente que usar un objeto literal, pero el primero tiene más funcionalidad

Si declaro una variable con const me aseguro de que…

  • Su valor sea immutable
  • Su valor sea conocido en tiempo de parsing del fichero
  • No pueda contener funciones
  • Su valor será seguro un número, una cadena, un booleano o un símbolo
  • No se le pueda asignar un nuevo valor (Correcto)

const solo evita reasignar la variable. const NO asegura immutabilidad. El siguiente código es válido (y el objeto muta):

const a={v:42}; 
a.v = 666; 

const NO asegura que el valor sea conocido en tiempo de parsing del fichero:

const a = (function() { 
    return math.random();
})(); 

En este ejemplo DEBE ejecutarse la función anónima para obtener el valor de a

const puede contener cualquier tipo de valor. Eso es completamente válido:

const a = function(n) { 
    return 'hello ' +n;
}

Evaluación final

En el siguiente código:

var saludo = "Hola";
function miFuncion() {
alert(saludo);
saludo = "Adios";
}
miFuncion();
alert(saludo);

¿Qué se muestra por pantalla? ¡Fíjate muy bien en el código y no hagas trampa ejecutándolo ;-)!

  • “Hola” y “Adios” (Correcto)
  • “Adios” y “Hola”
  • “Hola” y “Hola”
  • “Adios y “Adios”
  • Ninguna de las anteriores

¿Cómo puedes iterar sobre todos los valores de un array?

  • Usando un bucle for de 0 hasta array.length
  • Usando un bucle for de 0 hasta array.length - 1 (Correcto)
  • Usando un bucle for de 1 hasta array.length
  • Usando un bucle foreach
  • Usando un bucle for-in
  • Usando un bucle for-of (Correcto)

¿Es posible comprobar varios casos en una sola instrucción case en una estructura de control de flujo de comprobación de casos?

  • Sí, utilizando: case 1, 2, 3:
  • Sí, utilizando: case 1-3:
  • Sí, utilizando condiciones lógicas, como por ejemplo: case (x>=0 || x⇐5):
  • No, no es posible, aunque se puede simular con un switch(true) y luego usando condiciones lógicas, pero posee limitaciones (Correcto)
  • No, no es posible en JavaScript

¿Cómo recorrerías los elementos de una matriz usando para ello un bucle determinado y accediendo directamente con la variable contador del bucle, por ejemplo miMatriz[i]?

  • for(var i= 0; i< miMatriz.length; i++) (Correcto)
  • for(var i= 0; i⇐ miMatriz.length; i++)
  • for(var i= 1; i< miMatriz.length; i++)
  • for(var i= 1; i⇐ miMatriz.length; i++)

¿Puede una variable contener un generador?

  • No. Los generadores son siempre funciones de otros objetos
  • Sí, es posible definir un generador como una función sola y guardar dicha función en una variable (Correcto)
  • No. Aunque se pueden definir generadores como funciones solas, no se pueden guardar en variables

Cuando tienes una función que está trabajando como manejador de un evento, ¿qué referencia contendrá la variable this al utilizarla desde dentro del manejador?

  • Una referencia al objeto global (window)
  • Una referencia al objeto event que representa los datos del evento
  • Una referencia al elemento que ha provocado el evento
  • Una referencia al elemento que está capturando el evento, el cual no tiene que coincidir con el que lo ha provocado (Correcto)

El método sort de las matrices sirve para:

  • Ordenar de menor a mayor los elementos de una matriz
  • Ordenar de mayor a menor los elementos de una matriz
  • Ordenar de cualquier manera que deseemos los elementos de una matriz, usando para ello una función auxiliar que define cómo es la ordenación y que se pasa como parámetro (Correcto)
  • Este método no existe

¿Qué métodos se utilizan para insertar y quitar elementos del principio de una matriz, creando en la práctica una pila FIFO o cola?

  • push y pull
  • push y pop
  • slice y splice
  • unshift y shift (Correcto)

Has creado un proxy p, sobre un objeto obj. Dicho proxy intercepta las llamadas a propiedades. Tienes una función f, que recibe el objeto por parámetro y que llama a una propiedad prop del objeto, pero el proxy no intercepta nada. ¿Qué puede estar pasando?

  • Que a la función f le has pasado el objeto obj en lugar del proxy p como parámetro (Correcto)
  • Que el proxy no se ha inicializado
  • Las propiedades no pueden interceptarse, solo se pueden interceptar los métodos

¿Cómo podrías conseguir que un código se ejecutase a intervalos regulares de tiempo, entre ejecuciones completas, con toda certeza y sin que se pierdan o se retrasen ejecuciones, incluso aunque estos intervalos fuesen cortos y el proceso largo?

  • Simplemente usando setInterval, que está diseñado para eso
  • Utilizando setTimeout y estableciendo un nuevo setTimeout al final del código que se ejecuta (Correcto)
  • No es posible conseguir esto en casos extremos debido a que JavaScript se ejecuta siempre en un solo hilo y no tiene paralelismo
informatica/programacion/cursos/programacion_avanzada_javascript.txt · Última modificación: por tempwin