FullStackJS Camp
Módulo 4·teoria·6h
Objetivos de aprendizaje
  • Usar const/let apropiadamente y evitar var.
  • Aplicar destructuring en arrays y objetos.
  • Usar spread y rest en funciones y estructuras de datos.
  • Trabajar con optional chaining y nullish coalescing.
  • Conocer Set y Map y cuándo usarlos.
  • Organizar código con módulos ES (import/export).

Características ES6+

ES6 (ECMAScript 2015) y sus versiones posteriores transformaron JavaScript de un lenguaje de scripts a uno de desarrollo de aplicaciones serio. Este tema cubre las características que usarás todos los días.


const y let — Adiós a var

javascript
// var: scope de función, se puede redeclarar — evitar
var nombre = "Ana";
var nombre = "Luis"; // sin error → fuente de bugs

// let: scope de bloque, reasignable
let edad = 22;
edad = 23;

// const: scope de bloque, no reasignable (pero el objeto sí es mutable)
const PI = 3.14159;
// PI = 3; → TypeError: Assignment to constant variable

const usuario = { nombre: "Ana" };
usuario.nombre = "Luis"; // OK — mutación del objeto, no reasignación

Regla de oro: usa const por defecto. Cambia a let solo si necesitas reasignar.


Template Literals

javascript
const nombre = "Ana";
const edad   = 22;

// ES5
const msg1 = "Hola, " + nombre + ". Tienes " + edad + " años.";

// ES6 — template literal con ${}
const msg2 = `Hola, ${nombre}. Tienes ${edad} años.`;

// Expresiones dentro de ${}
const descuento = 0.15;
const precio    = 50000;
console.log(`Total: $${(precio * (1 - descuento)).toLocaleString("es-CL")}`);
// "Total: $42.500"

// Multilinea
const html = `
  <div class="card">
    <h2>${nombre}</h2>
    <p>Edad: ${edad}</p>
  </div>
`.trim();

Destructuring

Arrays

javascript
const colores = ["rojo", "verde", "azul", "amarillo"];

// Sin destructuring
const primero = colores[0];
const segundo = colores[1];

// Con destructuring
const [primero2, segundo2, , cuarto] = colores; // omite "azul" con ,
console.log(primero2); // "rojo"
console.log(cuarto);   // "amarillo"

// Swap de variables
let a = 1, b = 2;
[a, b] = [b, a];
console.log(a, b); // 2 1

// Valores por defecto
const [x = 0, y = 0, z = 0] = [10, 20];
console.log(z); // 0  (sin valor en el array)

Objetos

javascript
const producto = {
  id: 1,
  nombre: "Laptop",
  precio: 800000,
  categoria: { nombre: "Electrónica", id: 5 },
};

// Básico
const { nombre, precio } = producto;

// Renombrar al desestructurar
const { nombre: nombreProducto, precio: valor } = producto;
console.log(nombreProducto); // "Laptop"

// Valor por defecto
const { stock = 0 } = producto;
console.log(stock); // 0 (no existe en el objeto)

// Anidado
const { categoria: { nombre: catNombre } } = producto;
console.log(catNombre); // "Electrónica"

// En parámetros de función
function mostrarProducto({ nombre, precio, stock = 0 }) {
  console.log(`${nombre} | $${precio.toLocaleString("es-CL")} | Stock: ${stock}`);
}
mostrarProducto(producto);
// "Laptop | $800.000 | Stock: 0"

Spread ... y Rest ...

Spread — expandir

javascript
// Arrays
const frutas  = ["manzana", "pera"];
const verduras = ["zanahoria", "brócoli"];
const alimentos = [  ...frutas, ...verduras, "arroz"];
// ["manzana", "pera", "zanahoria", "brócoli", "arroz"]

// Copiar sin mutar
const original  = [1, 2, 3];
const copia     = [  ...original];
copia.push(4);
console.log(original); // [1, 2, 3] — intacto

// Objetos
const base      = { color: "rojo", tamaño: "M" };
const extendido = { ...base, tamaño: "L", precio: 5000 }; // sobreescribe tamaño
console.log(extendido); // { color: "rojo", tamaño: "L", precio: 5000 }

Rest — recoger el resto

javascript
// En arrays
const [cabeza, ...cola] = [1, 2, 3, 4, 5];
console.log(cabeza); // 1
console.log(cola);   // [2, 3, 4, 5]

// En objetos
const { id, ...resto } = { id: 1, nombre: "Ana", rol: "admin" };
console.log(id);    // 1
console.log(resto); // { nombre: "Ana", rol: "admin" }

// En parámetros
function sumar(...numeros) {
  return numeros.reduce((acc, n) => acc + n, 0);
}
console.log(sumar(1, 2, 3, 4)); // 10

Optional Chaining ?.

Evita errores al acceder a propiedades que podrían no existir:

javascript
const usuario = {
  nombre: "Ana",
  direccion: {
    ciudad: "Santiago",
  },
};

// Sin optional chaining → crash si direccion es null
// console.log(usuario.direccion.codigoPostal.cp); → TypeError

// Con optional chaining → retorna undefined en vez de crash
console.log(usuario.direccion?.codigoPostal?.cp); // undefined
console.log(usuario.telefono?.movil);             // undefined

// En métodos
const texto = null;
console.log(texto?.toUpperCase()); // undefined  (no crash)

// En arrays
const lista = null;
console.log(lista?.[0]); // undefined

Nullish Coalescing ??

Retorna el lado derecho solo cuando el izquierdo es null o undefined (no 0, "" o false):

javascript
// || tiene un problema: trata 0 y "" como falsy
const stock1 = 0;
console.log(stock1 || "sin stock");  // "sin stock" ← incorrecto
console.log(stock1 ?? "sin stock");  // 0          ← correcto

const nombre = "";
console.log(nombre || "Anónimo");  // "Anónimo" ← puede no ser lo que quieres
console.log(nombre ?? "Anónimo");  // ""        ← respeta el string vacío

// Combinado con ?.
const config = null;
const timeout = config?.servidor?.timeout ?? 3000;
console.log(timeout); // 3000 (default seguro)

Set — colección sin duplicados

javascript
const ids = new Set([1, 2, 3, 2, 1]);
console.log(ids.size); // 3

ids.add(4);
ids.delete(2);
console.log(ids.has(1)); // true

// Convertir a array
const arr = [  ...ids]; // [1, 3, 4]

// Eliminar duplicados de un array
const emails = ["a@x.com", "b@x.com", "a@x.com", "c@x.com"];
const unicos = [  ...new Set(emails)];
console.log(unicos); // ["a@x.com", "b@x.com", "c@x.com"]

Map — pares clave/valor mejorado

A diferencia de un objeto, Map acepta cualquier tipo como clave:

javascript
const cache = new Map();

cache.set("usuario:1", { nombre: "Ana" });
cache.set("usuario:2", { nombre: "Luis" });
cache.set(42, "clave numérica");

console.log(cache.get("usuario:1")); // { nombre: "Ana" }
console.log(cache.has(42));          // true
console.log(cache.size);             // 3

// Iterar
for (const [clave, valor] of cache) {
  console.log(`${clave} →`, valor);
}

// Convertir a array de pares
const pares = [  ...cache.entries()];

ES Modules — import / export

Organiza el código en archivos con responsabilidades claras:

javascript
// utils/formato.js
export function formatearPrecio(numero) {
  return new Intl.NumberFormat("es-CL", {
    style: "currency",
    currency: "CLP",
    maximumFractionDigits: 0,
  }).format(numero);
}

export const MONEDA_DEFAULT = "CLP";
javascript
// utils/validaciones.js
export function esEmailValido(email) {
  return /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(email);
}

// Export por defecto — solo uno por archivo
export default function validarFormulario(datos) {
  return Object.values(datos).every(v => v !== "" && v !== null);
}
javascript
// app.js
import validarFormulario, { esEmailValido } from "./utils/validaciones.js";
import { formatearPrecio, MONEDA_DEFAULT } from "./utils/formato.js";

console.log(esEmailValido("ana@email.com")); // true
console.log(formatearPrecio(25000));         // "$25.000"
console.log(MONEDA_DEFAULT);                  // "CLP"

Práctica

Práctica interactiva · JavaScript