JavaScript

img

JavaScript es uno de los lenguajes de programación más populares y fundamentales en el desarrollo web moderno. Su versatilidad y gran comunidad lo convierten en una herramienta clave para programadores de todos los niveles.


¿Qué es JavaScript?

JavaScript (JS) es un lenguaje de programación interpretado, orientado a objetos y basado en eventos, diseñado inicialmente para dotar de interactividad a las páginas web.

Diferencias clave frente a otros lenguajes:

2. ¿Para qué se usa?

JavaScript se utiliza en una amplia variedad de contextos, siendo el estándar para la programación en la web.

Aplicaciones principales:

Ideal cuando necesitas interactividad, comunicación en tiempo real, aplicaciones rápidas y prototipos ágiles.

3. ¿Qué puedo construir con JavaScript?

Con JavaScript puedes crear prácticamente cualquier tipo de aplicación moderna:

4. ¿Cuándo es más conveniente usarlo?

JavaScript es la mejor elección en los siguientes escenarios:

⚠️ Evítalo si el proyecto requiere alto rendimiento computacional, como simulaciones científicas o software de bajo nivel, donde lenguajes como C++ o Rust son más adecuados.

Buenas prácticas recomendadas

Patrones de diseño recomendados:


Resumen rápido

✅ Fortalezas principales:

⚠️ Debilidades principales:

🛠️ Cuándo usarlo:

🚫 Cuándo evitarlo:


Temas


Conceptos relacionados

Antes de aprender JavaScript o mientras lo estudias, es importante entender estos conceptos fundamentales:

1. Fundamentos de programación

2. Web y entorno de ejecución

3. Programación asíncrona

JavaScript es single-threaded pero puede manejar tareas asíncronas.

4. JSON y APIs

5. Ecosistema JavaScript

6. Principios de desarrollo

🔼 temas


Herramientas recomendadas

Estas herramientas te ayudarán a desarrollar, depurar y optimizar proyectos en JavaScript de manera profesional.

1. Editores y entornos de desarrollo

2. Control de versiones

3. Terminal y línea de comandos

4. Depuración y pruebas

Herramientas del navegador:

Frameworks de testing:

5. Automatización y bundlers

6. Entorno backend

🔼 temas


Snippets rápidos

Fragmentos de código reutilizables que facilitan tareas comunes.

1. Declaración de variables

const PI = 3.1416; // Constante (no cambia)
let nombre = "Juan"; // Variable que puede cambiar

2. Funciones

// Función tradicional
function saludar(nombre) {
  return `Hola, ${nombre}`;
}

// Función flecha (arrow function)
const despedir = (nombre) => `Adiós, ${nombre}`;

3. Condicional simple

const edad = 18;

if (edad >= 18) {
  console.log("Eres mayor de edad");
} else {
  console.log("Eres menor de edad");
}

4. Operador ternario

const mensaje = edad >= 18 ? "Mayor de edad" : "Menor de edad";
console.log(mensaje);

5. Bucles

// For
for (let i = 0; i < 5; i++) {
  console.log(i);
}

// While
let count = 0;
while (count < 5) {
  console.log(count++);
}

// For...of (recorrer arrays)
const frutas = ["Manzana", "Banana", "Pera"];
for (const fruta of frutas) {
  console.log(fruta);
}

6. Objetos y Arrays

const persona = {
  nombre: "Ana",
  edad: 25,
};

const colores = ["Rojo", "Verde", "Azul"];
console.log(persona.nombre); // Acceder a propiedad
console.log(colores[0]); // Acceder a elemento

7. Desestructuración

// Objetos
const { nombre, edad } = persona;
console.log(nombre, edad);

// Arrays
const [primero, segundo] = colores;
console.log(primero, segundo);

8. Fetch API (peticiones HTTP)

fetch("https://api.example.com/data")
  .then((res) => res.json())
  .then((data) => console.log(data))
  .catch((err) => console.error("Error:", err));

9. Async / Await

async function obtenerDatos() {
  try {
    const res = await fetch("https://api.example.com/data");
    const data = await res.json();
    console.log(data);
  } catch (error) {
    console.error("Error:", error);
  }
}

10. Exportar e importar módulos

// archivo.js
export const saludar = (nombre) => `Hola, ${nombre}`;

// app.js
import { saludar } from "./archivo.js";
console.log(saludar("Carlos"));

🔼 temas


Comandos

Sintaxis y comandos básicos cortos y directos para uso diario.

Variables y constantes

let edad = 25; // Variable modificable
const PI = 3.14; // Constante

Tipos de datos

let nombre = "Pedro"; // String
let edad = 30; // Number
let activo = true; // Boolean
let lista = [1, 2, 3]; // Array
let persona = { nombre: "Ana", edad: 25 }; // Objeto
let nada = null; // Null
let indefinido; // Undefined

Operadores básicos

// Aritméticos
let suma = 5 + 3;
let resta = 5 - 3;
let producto = 5 * 3;
let division = 5 / 3;

// Comparación
console.log(5 === "5"); // false (estricta)
console.log(5 == "5"); // true (no estricta)
console.log(5 !== 3); // true

// Lógicos
console.log(true && false); // false
console.log(true || false); // true
console.log(!true); // false

Funciones y callbacks

// Función simple
function sumar(a, b) {
  return a + b;
}

// Función como variable
const restar = function (a, b) {
  return a - b;
};

// Función flecha
const multiplicar = (a, b) => a * b;

Array Methods comunes

const numeros = [1, 2, 3, 4, 5];

numeros.forEach((n) => console.log(n)); // Recorrer
const dobles = numeros.map((n) => n * 2); // Nuevo array
const pares = numeros.filter((n) => n % 2 === 0); // Filtrar
const sumaTotal = numeros.reduce((acc, n) => acc + n, 0); // Reducir

Manejo de errores

try {
  const resultado = dividir(10, 0);
} catch (error) {
  console.error("Ocurrió un error:", error.message);
} finally {
  console.log("Proceso finalizado");
}

Clases y objetos

class Persona {
  constructor(nombre, edad) {
    this.nombre = nombre;
    this.edad = edad;
  }

  saludar() {
    return `Hola, me llamo ${this.nombre}`;
  }
}

const ana = new Persona("Ana", 25);
console.log(ana.saludar());

Promesas

const promesa = new Promise((resolve, reject) => {
  let exito = true;
  exito ? resolve("Todo bien") : reject("Error");
});

promesa
  .then((resultado) => console.log(resultado))
  .catch((error) => console.error(error));

Console y depuración

console.log("Información general");
console.warn("Advertencia");
console.error("Error crítico");
console.table([{ nombre: "Ana" }, { nombre: "Luis" }]); // Tabla

🔼 temas


Conceptos Claves

🟢 Básico

1. Tipos de datos primitivos en JavaScript

Primitivos:

string | number | bigint | boolean | undefined | null | symbol

Por referencia:

Diferencia:

let a = 10;
let b = a;
b = 20;
console.log(a); // 10 (no cambia)

let obj1 = { nombre: "Ana" };
let obj2 = obj1;
obj2.nombre = "Luis";
console.log(obj1.nombre); // "Luis"

2. Diferencia entre var, let y const

var

let

const

var x = 1;
let y = 2;
const z = 3;

Recomendación: usar let y const siempre que sea posible.

3. Hoisting (elevación)

Es el comportamiento donde declaraciones se mueven al inicio del ámbito antes de ejecutar el código.

console.log(x); // undefined
var x = 5;

// Equivalente a:
var x;
console.log(x);
x = 5;

Con let y const el hoisting ocurre pero no permite acceder a la variable antes de su declaración (temporal dead zone).

4. Funciones flecha y this

function tradicional() {
  console.log(this);
}

const flecha = () => {
  console.log(this);
};

En un objeto:

const obj = {
  nombre: "Ana",
  regular() {
    console.log(this.nombre); // "Ana"
  },
  arrow: () => {
    console.log(this.nombre); // undefined
  },
};
obj.regular();
obj.arrow();

5. Closures (cierres)

Un closure ocurre cuando una función recuerda variables de su contexto incluso después de que ese contexto haya terminado.

Ejemplo útil:

function contador() {
  let count = 0;
  return function () {
    count++;
    return count;
  };
}

const incrementar = contador();
console.log(incrementar()); // 1
console.log(incrementar()); // 2

Problema: variables compartidas:

function crearFunciones() {
  let arr = [];
  for (var i = 0; i < 3; i++) {
    arr.push(() => console.log(i));
  }
  return arr;
}

crearFunciones().forEach((fn) => fn()); // 3, 3, 3

Solución: usar let o crear un scope adicional.


🟡 Intermedio

6. Promesas y Promise.all / Promise.race

const promesa = new Promise((resolve, reject) => {
  setTimeout(() => resolve("Listo!"), 1000);
});

promesa.then(console.log);
Promise.all([p1, p2]).then((resultados) => console.log(resultados));
Promise.race([p1, p2]).then((primero) => console.log(primero));

7. Ciclo de vida de un evento DOM

  1. Capturing: evento baja desde el window hasta el elemento objetivo.
  2. Target: el evento llega al elemento específico.
  3. Bubbling: el evento sube de regreso al window.
element.addEventListener("click", handler, true); // Capturing
element.addEventListener("click", handler, false); // Bubbling

Detener propagación:

event.stopPropagation();

8. Event loop, microtasks y macrotasks

El event loop gestiona la ejecución de tareas en JavaScript.

Orden:

  1. Ejecutar todo el stack principal.
  2. Ejecutar todas las microtasks pendientes.
  3. Ejecutar la siguiente macrotask.
console.log("Inicio");
setTimeout(() => console.log("Macrotask"), 0);
Promise.resolve().then(() => console.log("Microtask"));
console.log("Fin");

Salida:

Inicio
Fin
Microtask
Macrotask

9. Inmutabilidad en JavaScript

La inmutabilidad significa que los datos no se modifican directamente, sino que se crea una copia nueva.

const original = { nombre: "Ana" };

// ❌ Mutación
original.nombre = "Luis";

// ✅ Inmutable
const copia = { ...original, nombre: "Luis" };

Métodos inmutables comunes en arrays:

10. Destructuring con valores por defecto y renombramiento

// Objetos
const usuario = { nombre: "Ana", edad: 25 };
const { nombre: n, edad = 18 } = usuario;
console.log(n, edad);

// Arrays
const colores = ["Rojo"];
const [primero = "Verde", segundo = "Azul"] = colores;
console.log(primero, segundo);

🔴 Avanzado

11. Iteradores y generadores

function* numeros() {
  yield 1;
  yield 2;
  yield 3;
}

const it = numeros();
console.log(it.next().value); // 1

Lazy evaluation: valores se generan bajo demanda.

12. Prototype y herencia prototípica

Cada objeto tiene un prototipo que define propiedades y métodos compartidos.

function Persona(nombre) {
  this.nombre = nombre;
}
Persona.prototype.saludar = function () {
  return `Hola, soy ${this.nombre}`;
};

const ana = new Persona("Ana");
console.log(ana.saludar());

Si modificas el prototipo después: los objetos existentes también acceden a los nuevos métodos.

13. Manejo de errores en código asíncrono

Con promesas:

fetch("url")
  .then((res) => res.json())
  .catch((error) => console.error(error));

Con async/await:

async function cargarDatos() {
  try {
    const res = await fetch("url");
    const data = await res.json();
  } catch (error) {
    console.error(error);
  }
}

Consejo: siempre usar try/catch y .catch() para evitar errores silenciosos.

14. Concepto de this

const obj = {
  nombre: "Ana",
  regular: function () {
    console.log(this.nombre);
  },
  flecha: () => {
    console.log(this.nombre);
  },
};
obj.regular(); // Ana
obj.flecha(); // undefined

15. Shadow DOM, Virtual DOM y Regular DOM

Uso recomendado:

🔼 temas