Skip to content

Unidad 1: Fundamentos Avanzados de JavaScript

Objetivo: Profundizar en las características clave del lenguaje JavaScript y su uso en aplicaciones modernas.


1.1 Diferencias entre var, let y const

¿Qué vamos a aprender?

En este apartado conoceremos las diferencias entre var, let y const, tres formas de declarar variables en JavaScript. Comprenderemos su ámbito, si pueden ser reasignadas y cómo el hoisting afecta su comportamiento.

Ámbito y Uso Correcto de Cada Uno

JavaScript permite declarar variables usando var, let y const, pero cada una tiene diferencias importantes:

Tipo Ámbito Reasignable Hoisting
var Función ✅ Sí ✅ Se mueve al inicio con undefined
let Bloque ✅ Sí ❌ No se inicializa automáticamente
const Bloque ❌ No ❌ No se inicializa automáticamente

Ejemplo de var, let y const

function pruebaVar() {
    if (true) {
        var x = 10;
    }
    console.log(x); // ✅ Funciona, x tiene ámbito de función
}
pruebaVar();

function pruebaLet() {
    if (true) {
        let y = 20;
    }
    console.log(y); // ❌ Error, y tiene ámbito de bloque
}
pruebaLet();
En este ejemplo, var tiene ámbito de función, por lo que la variable x está disponible fuera del bloque if. En cambio, let tiene ámbito de bloque y provoca un error al intentar acceder a y fuera del if.

Hoisting y Problemas Comunes

El Hoisting es un comportamiento de JavaScript que mueve las declaraciones de variables y funciones al inicio del ámbito. Esto puede causar problemas si no se entiende correctamente.

Ejemplo de Hoisting con var y let

1
2
3
4
5
console.log(a); // ✅ Undefined
var a = 5;

console.log(b); // ❌ Error: Cannot access 'b' before initialization
let b = 10;
var es movida al inicio y su valor es undefined antes de la asignación. let no permite el acceso antes de su declaración, lo que ayuda a evitar errores.

Ejercicios

Practica con var, let y const

  1. Declara una variable con var, let y const y prueba a reasignarlas. ¿Qué sucede?
  2. Crea un for con var y otro con let. Accede a las variables fuera del bucle y analiza el resultado.
Solución
1
2
3
4
5
6
7
8
var x = 5;
x = 10; // ✅ Se puede reasignar

let y = 15;
y = 20; // ✅ Se puede reasignar

const z = 25;
z = 30; // ❌ Error: No se puede reasignar una constante

1.2 Funciones de Flecha (=>) y Desestructuración de Objetos y Arrays

¿Qué vamos a aprender?

Aprenderemos cómo las funciones de flecha simplifican la sintaxis y eliminan el problema del this. También veremos cómo extraer valores de objetos y arrays de manera eficiente con la desestructuración.

Funciones de Flecha (=>)

Las funcines de flecha (arrow functions) son una forma más concisa de escribir funciones en JavaScript. Se definen con la sintaxis () => {} y tienen varias ventajas:

  • Sintaxis más corta: Elimina la necesidad de function y return.
  • this consistente: No cambia el valor de this dentro de la función.
  • Útiles para funciones anónimas: Simplifica el código en callbacks y eventos.

Aparecen en ES6 y son muy comunes en aplicaciones modernas.

Conversión de función tradicional a función de flecha

1
2
3
4
5
6
7
8
9
// Función tradicional
function sumar(a, b) {
    return a + b;
}
console.log(sumar(5, 3));

// Función de flecha
const sumarFlecha = (a, b) => a + b;
console.log(sumarFlecha(5, 3));

La función de flecha reduce el código eliminando la necesidad de function y return si es de una sola línea. Si es de más de una línea, se deben usar llaves {} y return.

Desestructuración de Objetos y Arrays

Ejemplo de desestructuración de objetos y arrays

// Desestructuración de un objeto
const persona = { nombre: "Ana", edad: 30, ciudad: "Madrid" };
const { nombre, edad } = persona;
console.log(nombre, edad); // Ana 30
const { ciudad: localidad } = persona;
console.log(localidad); // Madrid

// Desestructuración de un array
const numeros = [10, 20, 30];
const [primero, segundo] = numeros;
console.log(primero, segundo); // 10 20
La desestructuración permite extraer valores de un objeto o un array directamente sin acceder a cada propiedad individualmente.

Operador Spread (...)

El operador spread (...) permite combinar arrays o objetos de forma sencilla. Se usa para copiar elementos de un array o un objeto en otro.

Ejemplo de operador spread

1
2
3
4
const array1 = [1, 2, 3];
const array2 = [4, 5, 6];
const combinado = [...array1, ...array2];
console.log(combinado); // [1, 2, 3, 4, 5, 6]
El operador spread permite combinar dos arrays en uno solo de forma rápida y sencilla.

Ejercicios

Practica con funciones de flecha y desestructuración

  1. Convierte una función tradicional que multipique dos números una función de flecha.
  2. Crea una función que reciba dos arrays y los combine en uno solo usando el operador spread.
  3. A partir del objeto coche {marca: " Toyota", modelo: "Corolla" }, desestructura las propiedades marca y modelo y muéstralas en la consola.
Solución
const multiplicar = (a, b) => a * b;
console.log(multiplicar(4, 5)); // 20

function combinarArrays(arr1, arr2) {
    return [...arr1, ...arr2];
}

const coche = { marca: "Toyota", modelo: "Corolla" };
const { marca, modelo } = coche;
console.log(marca, modelo); // Toyota Corolla

1.3 Modularización con import/export

¿Qué vamos a aprender?

En este apartado aprenderemos cómo estructurar el código en módulos reutilizables utilizando import y export. Modularizar nuestro código nos permitirá mantenerlo organizado, facilitar su mantenimiento y promover la reutilización de funciones y constantes en diferentes partes de nuestro proyecto.

Uso de export e import en JavaScript

JavaScript permite dividir el código en módulos, archivos individuales que exportan y utilizan funciones, variables u objetos.

Ejemplo de Exportación y Importación de Múltiples Elementos

math.js
// Archivo math.js
export function suma(a, b) {
    return a + b;
}

export function resta(a, b) {
    return a - b;
}

export const PI = 3.1416;
app.js
1
2
3
4
5
6
// Archivo app.js
import { suma, resta, PI } from './math.js';

console.log(suma(4, 5)); // 9
console.log(resta(10, 3)); // 7
console.log(PI); // 3.1416
En este ejemplo, math.js exporta varias funciones y constantes, que luego se importan en app.js.

Uso de export default

Si solo queremos exportar un elemento principal de un archivo, usamos export default.

Ejemplo de export default

operaciones.js
1
2
3
4
// Archivo operaciones.js
export default function multiplicar(a, b) {
    return a * b;
}
app.js
1
2
3
4
// Archivo app.js
import multiplicar from './operaciones.js';

console.log(multiplicar(4, 5)); // 20
En este caso, al importar la función, no es necesario usar llaves {}. Además, podemos cambiar el nombre de la función al importarla si lo deseamos.

Ejemplo Completo con Exportación Mixta

Podemos combinar export y export default en el mismo archivo.

Ejemplo de Exportación Mixta

calculadora.js
// Archivo calculadora.js
export function dividir(a, b) {
    return a / b;
}

export const GRAVEDAD = 9.81;

export default function potencia(base, exponente) {
    return base ** exponente;
}
app.js
1
2
3
4
5
6
// Archivo app.js
import potencia, { dividir, GRAVEDAD } from './calculadora.js';

console.log(dividir(10, 2)); // 5
console.log(potencia(2, 3)); // 8
console.log(GRAVEDAD); // 9.81
En este ejemplo, potencia se importa sin llaves {} porque es un export default, mientras que dividir y GRAVEDAD se importan con llaves {}.

También podemos crear las funciones y constantes en un solo archivo y exportarlas al final. Cuando el módulo es largo es una manera de mantener el código más organizado.

Ejemplo de Exportación al Final del Archivo

operaciones.js
// Archivo operaciones.js
function sumar(a, b) {
    return a + b;
}

function restar(a, b) {
    return a - b;
}

const PI = 3.1416;

export { sumar, restar, PI };
app.js
1
2
3
4
5
6
// Archivo app.js
import { sumar, restar, PI } from './operaciones.js';

console.log(sumar(4, 5)); // 9
console.log(restar(10, 3)); // 7
console.log(PI); // 3.1416
En este caso, las funciones y la constante se definen al principio del archivo y se exportan al final.

Ejercicios

Practica con módulos en JavaScript

  1. Crea dos archivos JavaScript: modulo.js y main.js.
  2. En modulo.js, exporta dos funciones (saludo y despedida con el parámetro nombre) y una constante con el nombre de la aplicación.
  3. En main.js, importa estos elementos y úsalos en console.log().
Solución

// modulo.js
export function saludo(nombre) {
    return `Hola, ${nombre}!`;
}

export function despedida(nombre) {
    return `Adiós, ${nombre}!`;
}

export const APP_NOMBRE = "Mi Aplicación";
1
2
3
4
5
6
// main.js
import { saludo, despedida, APP_NOMBRE } from './modulo.js';

console.log(saludo("Carlos")); // Hola, Carlos!
console.log(despedida("Ana")); // Adiós, Ana!
console.log(`Bienvenido a ${APP_NOMBRE}`); // Bienvenido a Mi Aplicación

Con este apartado, hemos aprendido cómo dividir nuestro código en módulos reutilizables, mejorando la organización y el mantenimiento de nuestros proyectos en JavaScript.