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ónRegla 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)); // 10Optional 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]); // undefinedNullish 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