Guía Fundamental de JavaScript 1. Introducción JavaScript es un lenguaje dinámico y flexible utilizado tanto en el lado del cliente como en el servidor. Para escribir código claro y libre de errores, es crucial entender cómo se declaran las variables, qué operadores se utilizan y cuáles son las buenas prácticas a seguir. Esta guía integra la teoría con ejemplos prácticos y responde preguntas comunes que fortalecen el conocimiento de estos fundamentos. 2. Variables en JavaScript Las variables son contenedores que almacenan datos. Se declaran mediante palabras clave específicas que determinan el alcance y comportamiento. 2.1. Palabras clave para declarar variables En JavaScript existen tres palabras clave: var - - Teoría: Forma tradicional de declarar variables. Tiene alcance global o de función, lo que puede ocasionar problemas de hoisting (elevación) y errores en bloques de código. Ejemplo: var mensaje = "Hola con var"; console.log(mensaje); // Imprime: Hola con var let - - Teoría: Introducida en ES6, permite declarar variables con alcance de bloque, ofreciendo mayor control y reduciendo errores. Ejemplo: let saludo = "Hola con let"; if (true) { let saludo = "Hola dentro del bloque"; console.log(saludo); // Imprime: Hola dentro del bloque } console.log(saludo); // Imprime: Hola con let const - - Teoría: También introducida en ES6, se utiliza para declarar variables cuyos valores no se deben reasignar. Con objetos o arrays, aunque la variable no se pueda reasignar, sus propiedades o elementos pueden modificarse. Ejemplo: const PI = 3.1416; console.log("Valor de PI:", PI); // Imprime: Valor de PI: 3.1416 const persona = { nombre: "Ana" }; persona.nombre = "María"; // Se permite modificar la propiedad console.log(persona); // Imprime: { nombre: "María" } 2.2. ¿Qué declaración se debe evitar y por qué? Teoría: Se recomienda evitar var porque su alcance es global o de función, lo que puede generar problemas de hoisting y errores inesperados en estructuras de bloques. Se prefiere el uso de let y const para tener un alcance de bloque claro. Ejemplo: function ejemploVar() { if (true) { var numero = 10; } console.log(numero); // Imprime 10, aunque la variable fue declarada dentro de un bloque } ejemploVar(); 2.3. Reglas para nombrar variables Teoría: - - - - - Inicio: Deben comenzar con una letra, un guion bajo (_) o un signo de dólar ($) No iniciar con números: No pueden comenzar con dígitos Sensibilidad: Son case-sensitive (por ejemplo, nombre y Nombre son distintas) Palabras reservadas: No se deben utilizar palabras reservadas del lenguaje Convención: Se recomienda utilizar nombres descriptivos y la convención camelCase Ejemplo: let primerNombre = "Luis"; let _edad = 28; let $salario = 1500; 3. Operadores en JavaScript Los operadores permiten realizar operaciones matemáticas, lógicas y de asignación sobre valores y variables. Cada tipo de operador se explica junto con ejemplos. 3.1. Operadores Aritméticos Teoría: Realizan operaciones matemáticas básicas como suma, resta, multiplicación, división, exponenciación y módulo. - - - - - - Suma (+) Resta (-) Multiplicación (*) División (/) Exponenciación (**) Módulo (%): Devuelve el residuo de la división Ejemplo: let a = 10, b = 3; console.log("Suma:", a + b); // Imprime: 13 console.log("Resta:", a - b); // Imprime: 7 console.log("Multiplicación:", a * b); // Imprime: 30 console.log("División:", a / b); // Imprime: 3.3333... console.log("Exponenciación:", a ** b); // Imprime: 1000 console.log("Módulo:", a % b); // Imprime: 1 (residuo de 10 / 3) 3.2. Operadores de Asignación Teoría: Se utilizan para asignar valores a variables. Incluyen: - - Asignación simple (=) Asignación compuesta: +=, -=, *=, /=, %= Ejemplo: let contador = 5; contador += 2; // Equivalente a contador = contador + 2 console.log("Contador:", contador); // Imprime: 7 3.3. Operadores de Comparación Teoría: Se usan para comparar valores y determinar igualdad o diferencia. - - - - Igualdad no estricta (==): Compara valores realizando conversión de tipos si es necesario Igualdad estricta (===): Compara valor y tipo sin convertir Desigualdad: != y !== Relacionales: >, <, >=, <= Ejemplo: let num = 25; console.log("num == '25':", num == "25"); // Imprime: true (coerción de tipos) console.log("num === '25':", num === "25"); // Imprime: false (tipos diferentes) console.log("num > 20:", num > 20); // Imprime: true 3.4. Operadores Lógicos Teoría: Permiten combinar condiciones lógicas: - - - AND (&&) OR (||) NOT (!) Ejemplo: let edad = 30; let tieneLicencia = true; if (edad > 18 && tieneLicencia) { console.log("Puede conducir"); } else { console.log("No cumple los requisitos"); } // Imprime: Puede conducir 3.5. Operador Módulo (Resto) Teoría: El operador % calcula el residuo de la división entre dos números. Ejemplo: let residuo = 5 % 2; console.log("El residuo de 5 % 2 es:", residuo); // Imprime: 1 3.6. Incremento y Decremento Teoría: Sirven para aumentar o disminuir el valor de una variable en 1. - - Incremento (++) Decremento (--) Ejemplo: let numero = 10; numero++; // Incrementa a 11 console.log("Después de incrementar:", numero); // Imprime: 11 numero--; // Decrementa a 10 console.log("Después de decrementar:", numero); // Imprime: 10 3.7. Prefijo vs. Postfijo en Incremento/Decremento Teoría: - - Prefijo (++x o --x): Se realiza la operación antes de usar el valor en una expresión Postfijo (x++ o x--): Se utiliza el valor actual en la expresión y luego se modifica Ejemplo: let x = 5; console.log("Postfijo (x++):", x++); // Imprime 5 y luego x pasa a ser 6 console.log("Valor de x después del postfijo:", x); // Imprime: 6 x = 5; // Reiniciamos el valor console.log("Prefijo (++x):", ++x); // x se incrementa a 6 y se imprime 6 3.8. Operador Unario (+) Teoría: Convierte cadenas de texto que representan números en valores numéricos. Ejemplo: let cadenaNumero = "10"; let numeroConvertido = +cadenaNumero; console.log("Tipo y valor después de usar +:", typeof numeroConvertido, numeroConvertido); // Imprime: number 10 3.9. Precedencia de Operadores Teoría: La precedencia determina el orden en el que se evalúan las operaciones en una expresión. Por ejemplo, la multiplicación se realiza antes que la suma. Se pueden usar paréntesis para modificar este orden. Ejemplo: let resultado1 = 2 + 3 * 4; // Sin paréntesis: 2 + (3*4) = 14 let resultado2 = (2 + 3) * 4; // Con paréntesis: (2+3) * 4 = 20 console.log("Resultado sin paréntesis:", resultado1); // Imprime: 14 console.log("Resultado con paréntesis:", resultado2); // Imprime: 20 3.10. Comparación: == vs === Teoría: - - == compara valores permitiendo la conversión de tipos (coerción) === compara valor y tipo de forma estricta, sin conversión Ejemplo: console.log(5 == "5"); // true, porque convierte "5" a número console.log(5 === "5"); // false, porque los tipos son diferentes 3.11. Resultados NaN Teoría: NaN (Not a Number) se obtiene cuando una operación matemática falla o se intenta convertir un valor no numérico a número. Ejemplo: let operacionInvalida = "hola" - 3; console.log("Resultado de una operación inválida:", operacionInvalida); // Imprime: NaN 4. Herramientas de Desarrollo 4.1. Acceso a las herramientas de desarrollador y la consola Teoría: Las herramientas de desarrollador permiten inspeccionar, depurar y probar el código. En la mayoría de los navegadores se accede presionando: - - - Windows/Linux: F12 o Ctrl+Shift+I Mac: Cmd+Option+I También se puede hacer clic derecho sobre la página y seleccionar "Inspeccionar" o "Inspeccionar elemento" 4.2. Registro de información en la consola Teoría: Para visualizar mensajes, valores o errores durante la ejecución del código, se usa la función console.log(). Ejemplo: console.log("Este es un mensaje de depuración en la consola"); Tipos de Datos y Control de Flujo 2. Data Types en JavaScript 2.1. Los ocho data types En JavaScript existen ocho tipos de datos fundamentales: Primitivos: - - - - - - - String: Cadena de texto Number: Números (enteros o decimales) Boolean: Valores de verdadero o falso Undefined: Una variable declarada sin asignación Null: Representa la ausencia intencional de valor Symbol: Un valor único e inmutable (introducido en ES6) BigInt: Números enteros de precisión arbitraria No primitivo: - Object: Colección de propiedades; incluye arrays, funciones, etc. 2.2. Datos primitivos y no primitivos Los tipos primitivos (string, number, boolean, undefined, null, symbol y bigint) almacenan datos simples e inmutables. El tipo Object, en cambio, permite agrupar datos y funcionalidades, y es mutable. 2.3. Strings y tipos de comillas Las strings son secuencias de caracteres que representan texto. Existen tres formas de definirlas: Comillas simples ('') y dobles (""): - - Son equivalentes Se utilizan para definir strings sin la capacidad directa de incorporar variables o expresiones Backticks (``): - - Permiten crear template literals Facilitan la inserción de variables o expresiones en la cadena mediante ${...} Ejemplo: // Uso de comillas simples y dobles let saludo1 = 'Hola Mundo'; let saludo2 = "Hola Mundo"; // Uso de backticks para template literals let nombre = "Ana"; let saludo3 = `Hola, ${nombre}!`; // Se inserta la variable dentro del string console.log(saludo3); // Imprime: Hola, Ana! 2.4. Métodos en los strings Los strings disponen de numerosos métodos útiles: - - - - - - toUpperCase() / toLowerCase(): Convierte el texto a mayúsculas o minúsculas slice(), substring(): Extraen partes de la cadena replace(): Sustituye parte del texto por otro trim(): Elimina espacios en blanco al inicio y final de la cadena indexOf() / lastIndexOf(): Ubican la posición de un texto dentro de la cadena includes(): Determina si una cadena contiene un cierto texto Ejemplo: let mensaje = " Hola Mundo "; console.log(mensaje.toUpperCase()); // Imprime: " HOLA MUNDO " console.log(mensaje.trim()); // Imprime: "Hola Mundo" console.log(mensaje.slice(3, 7)); // Imprime: "Hola" console.log(mensaje.replace("Mundo", "JS")); // Imprime: " Hola JS " 2.5. Características avanzadas de strings Concatenación let parte1 = "Hola"; let parte2 = "Mundo"; let saludo = parte1 + " " + parte2; // Resultado: "Hola Mundo" // Con template literal: saludo = `${parte1} ${parte2}`; Escape characters let cita = "El dijo: \"Hola Mundo\""; console.log(cita); // Imprime: El dijo: "Hola Mundo" Multi-line strings let mensajeMultiLinea = `Esta es la primera línea y esta es la segunda línea.`; Indexado y longitud let ejemplo = "JavaScript"; console.log(ejemplo[0]); console.log(ejemplo.length); // Imprime: J // Imprime: 10 Métodos de búsqueda let frase = "Aprender JavaScript es divertido"; console.log(frase.indexOf("JavaScript")); // Posición inicial de "JavaScript" console.log(frase.includes("divertido")); // true console.log(frase.startsWith("Aprender")); // true console.log(frase.endsWith("divertido")); // true 3. Condicionales en JavaScript 3.1. if/else La estructura if/else permite ejecutar código basado en condiciones. let edad = 20; if (edad >= 18) { console.log("Eres mayor de edad."); } else { console.log("Eres menor de edad."); } 3.2. switch statement El switch evalúa múltiples condiciones basadas en un mismo valor. let color = "rojo"; switch (color) { case "azul": console.log("El color es azul."); break; case "rojo": console.log("El color es rojo."); break; default: console.log("Color no reconocido."); } 3.3. Operador ternario Forma concisa de escribir una condición simple: let edad = 16; let mensaje = (edad >= 18) ? "Eres mayor de edad." : "Eres menor de edad."; console.log(mensaje); 3.4. Anidamiento (Nesting) Permite evaluar múltiples niveles de condiciones: let nota = 85; if (nota >= 60) { if (nota >= 90) { console.log("Excelente"); } else { console.log("Aprobado"); } } else { console.log("Reprobado"); } 4. Operadores Lógicos y Comparación 4.1. Operadores lógicos - - - AND (&&): Devuelve true si ambas condiciones son verdaderas OR (||): Devuelve true si al menos una condición es verdadera NOT (!): Invierte el valor booleano let a = true; let b = false; console.log(a && b); // false console.log(a || b); // true console.log(!a); // false 4.2. Operadores de comparación - - - Igualdad: == (con coerción) y === (estricta) Desigualdad: != y !== Relacionales: >, <, >=, <= let numero = 10; console.log(numero == "10"); // true (coerción) console.log(numero === "10"); // false (tipos diferentes) console.log(numero > 5); // true 5. Valores Truthy y Falsy Valores falsy - - - - - - false 0 "" (cadena vacía) null undefined NaN Valores truthy - - - - - Cualquier valor que no sea falsy Objetos y arrays (incluso vacíos) Números distintos de 0 Strings no vacías El valor booleano true Ejemplo: let valor = ""; if (valor) { console.log("El valor es truthy."); } else { console.log("El valor es falsy."); } Funciones en JavaScript Teoría de Funciones Una función en JavaScript es un objeto que puede ser invocado, aceptar argumentos y devolver un valor. Es un bloque de código reutilizable diseñado para realizar una tarea específica. Características Fundamentales - First-class Citizens: Las funciones son objetos de primera clase, lo que significa que pueden: - - - - - Ser asignadas a variables Ser pasadas como argumentos a otras funciones Ser devueltas desde otras funciones Tener propiedades y métodos Contexto de Ejecución: Cada llamada a una función crea un nuevo contexto de ejecución con: - - - Variable Environment: Almacena las variables locales Scope Chain: Cadena de ámbitos para la resolución de variables This Binding: Referencia al objeto que invoca la función Tipos de Funciones según su Definición 1. Declaración de Función: function saludar(nombre) { return "¡Hola, " + nombre + "!"; } - - Se elevan (hoisting) completamente Disponibles en todo el ámbito donde están definidas 2. Expresión de Función: const saludar = function(nombre) { return "¡Hola, " + nombre + "!"; }; - - No se elevan como las declaraciones Útiles para asignación a variables o como argumentos 3. Funciones Flecha (Arrow Functions): const saludar = (nombre) => { return "¡Hola, " + nombre + "!"; }; - - - - Sintaxis más concisa No tienen su propio this (heredan del contexto circundante) No pueden ser utilizadas como constructores (sin new) No tienen el objeto arguments El Valor this en Funciones El valor de this depende de cómo se invoca la función: - - - - Invocación como método: this se refiere al objeto que contiene el método Invocación como función: this se refiere al objeto global (o undefined en modo estricto) Invocación como constructor: this se refiere al nuevo objeto creado Invocación mediante call/apply/bind: this se refiere al objeto especificado como primer argumento Closures (Cierres) Un closure ocurre cuando una función tiene acceso al ámbito léxico en el que fue definida, incluso después de que la función externa haya terminado de ejecutarse. Propiedades clave: - - - Permiten la encapsulación de datos (variables privadas) Mantienen el estado entre llamadas a funciones Son la base de muchos patrones de diseño en JavaScript Estructura básica: function externa() { const variableExterna = "Soy externa"; function interna() { console.log(variableExterna); // Accede a variable de la función externa } return interna; // Devuelve la función interna } const miClosure = externa(); miClosure(); // "Soy externa" Patrón Módulo Los closures permiten implementar el patrón módulo para encapsular datos: const contador = (function() { let valor = 0; // Variable privada return { incrementar: function() { valor++; return valor; }, decrementar: function() { valor--; return valor; }, obtenerValor: function() { return valor; } }; })(); Declaración de Funciones function saludar(nombre) { return "¡Hola, " + nombre + "!"; } // Uso de la función console.log(saludar("María")); // Resultado: ¡Hola, María! Expresión de Función const saludar = function(nombre) { return "¡Hola, " + nombre + "!"; }; // Uso de la función console.log(saludar("Juan")); // Resultado: ¡Hola, Juan! Funciones Flecha (Arrow Functions) // Función flecha con múltiples parámetros const sumar = (a, b) => { return a + b; }; // Versión abreviada para retornos simples const multiplicar = (a, b) => a * b; // Función flecha sin parámetros const saludarMundo = () => "¡Hola mundo!"; // Función flecha con un solo parámetro (paréntesis opcionales) const cuadrado = num => num * num; // Uso console.log(sumar(5, 3)); // 8 console.log(multiplicar(4, 2)); // 8 console.log(saludarMundo()); console.log(cuadrado(5)); // ¡Hola mundo! // 25 Parámetros y Argumentos // Parámetros por defecto function saludar(nombre = "Invitado") { return "¡Hola, " + nombre + "!"; } console.log(saludar()); // ¡Hola, Invitado! console.log(saludar("Pedro")); // ¡Hola, Pedro! // Parámetro rest (resto de parámetros) function sumarTodos(...numeros) { return numeros.reduce((total, num) => total + num, 0); } console.log(sumarTodos(1, 2, 3, 4)); // 10 Funciones Anónimas // Función anónima como callback setTimeout(function() { console.log("Este mensaje aparece después de 2 segundos"); }, 2000); // Con arrow function setTimeout(() => console.log("Arrow function como callback"), 2000); Closures (Cierres) Los closures permiten a una función acceder a variables de su entorno externo incluso después de que la función externa haya terminado de ejecutarse. function crearContador() { let contador = 0; return function() { contador++; return contador; }; } const miContador = crearContador(); console.log(miContador()); // 1 console.log(miContador()); // 2 console.log(miContador()); // 3 Funciones Recursivas function factorial(n) { if (n <= 1) return 1; return n * factorial(n - 1); } console.log(factorial(5)); // 120 (5 * 4 * 3 * 2 * 1) Bucles (Loops) en JavaScript Elección del Tipo de Bucle - - for: Cuando se conoce el número de iteraciones. while: Cuando no se conoce el número de iteraciones pero se conoce la condición de parada. - - - - do-while: Cuando se necesita ejecutar el código al menos una vez. for-of: Para recorrer elementos de colecciones iterables. for-in: Para recorrer propiedades de objetos. Métodos de array (forEach, map, etc.): Para operaciones específicas en arrays. Bucle For // Estructura básica for (let i = 0; i < 5; i++) { console.log("Iteración número: " + i); } // Recorrer un array const frutas = ["Manzana", "Plátano", "Naranja", "Pera"]; for (let i = 0; i < frutas.length; i++) { console.log(frutas[i]); } Bucle For...Of Específicamente diseñado para recorrer elementos iterables como arrays. const frutas = ["Manzana", "Plátano", "Naranja", "Pera"]; for (const fruta of frutas) { console.log(fruta); } Bucle For...In Diseñado para recorrer las propiedades de un objeto. const persona = { nombre: "Ana", edad: 28, profesion: "Ingeniera" }; for (const propiedad in persona) { console.log(propiedad + ": " + persona[propiedad]); } Bucle While let contador = 0; while (contador < 5) { console.log("Contador: " + contador); contador++; } Bucle Do...While Se ejecuta al menos una vez, incluso si la condición es falsa. let contador = 0; do { console.log("Contador: " + contador); contador++; } while (contador < 5); Control de Bucles: break y continue // break - detiene el bucle for (let i = 0; i < 10; i++) { if (i === 5) { break; } console.log(i); // Imprime del 0 al 4 } // continue - salta a la siguiente iteración for (let i = 0; i < 10; i++) { if (i === 5) { continue; } console.log(i); // Imprime del 0 al 9, excepto el 5 } Bucles Anidados // Crear una matriz (array bidimensional) for (let i = 0; i < 3; i++) { for (let j = 0; j < 3; j++) { console.log(`Posición: [${i}, ${j}]`); } } Arrays en JavaScript Teoría de Arrays Un array en JavaScript es una estructura de datos que permite almacenar múltiples valores en una sola variable. A diferencia de los arrays en otros lenguajes, los arrays en JavaScript son dinámicos (pueden cambiar de tamaño) y heterogéneos (pueden contener diferentes tipos de datos). Características Fundamentales - - - - - Colección indexada: Los elementos se acceden mediante índices numéricos que comienzan en 0. Dinámicos: Pueden cambiar de tamaño después de ser creados. Heterogéneos: Pueden contener elementos de diferentes tipos. Orden preservado: Mantienen el orden de inserción de los elementos. Objetos especiales: En JavaScript, los arrays son objetos con propiedades y métodos especiales. Funcionamiento Interno Internamente, los arrays en JavaScript: - - - - Son objetos donde las claves son índices numéricos convertidos a strings. Tienen una propiedad especial length que indica el número de elementos. Heredan métodos del prototipo Array.prototype. Están optimizados por los motores de JavaScript para operaciones comunes. Complejidad Temporal Operaciones comunes y su complejidad: - - - - - Acceso: O(1) - Acceso directo por índice Búsqueda: O(n) - Búsqueda lineal (indexOf, includes) Inserción/Eliminación al final: O(1) - Operaciones push/pop Inserción/Eliminación al principio: O(n) - Operaciones unshift/shift (requieren reindexar) Inserción/Eliminación en medio: O(n) - Operaciones splice (requieren reindexar) Arrays vs Objetos Característica Arrays Objetos Índices Numéricos, secuenciales Strings, cualquier valor Característica Arrays Objetos Ordenación Preservan orden No garantizan orden Longitud Propiedad length No tienen propiedad de longitud Iteración Optimizados para iteración secuencial No optimizados para iteración secuencial Propósito Datos ordenados secuencialmente Datos relacionados con propiedades clave-valor Arrays y Paso por Referencia Los arrays se pasan por referencia, no por valor: const arr1 = [1, 2, 3]; const arr2 = arr1; // arr2 apunta a la misma referencia que arr1 arr2.push(4); console.log(arr1); // [1, 2, 3, 4] - arr1 también se modifica Arrays Dispersos (Sparse Arrays) Son arrays con "huecos" (elementos no definidos): const disperso = [1, , 3]; // El índice 1 es un hueco console.log(disperso.length); // 3 console.log(disperso[1]); // undefined Creación de Arrays // Array literal const numeros = [1, 2, 3, 4, 5]; // Constructor Array const frutas = new Array("Manzana", "Plátano", "Naranja"); // Array con diferentes tipos de datos const mixto = [1, "texto", true, null, { nombre: "Juan" }, [1, 2, 3]]; // Array vacío const vacio = []; Acceso a Elementos const colores = ["rojo", "verde", "azul", "amarillo"]; console.log(colores[0]); // rojo (el primer elemento tiene índice 0) console.log(colores[2]); // azul // Último elemento console.log(colores[colores.length - 1]); // amarillo // Índices negativos (usando at() - ES2022) console.log(colores.at(-1)); // amarillo (último elemento) console.log(colores.at(-2)); // azul (penúltimo elemento) Modificación de Arrays const frutas = ["Manzana", "Plátano", "Naranja"]; // Modificar un elemento frutas[1] = "Uva"; console.log(frutas); // ["Manzana", "Uva", "Naranja"] // Añadir un elemento al final frutas.push("Pera"); console.log(frutas); // ["Manzana", "Uva", "Naranja", "Pera"] // Añadir un elemento al principio frutas.unshift("Fresa"); console.log(frutas); // ["Fresa", "Manzana", "Uva", "Naranja", "Pera"] // Eliminar el último elemento const ultimaFruta = frutas.pop(); console.log(ultimaFruta); // "Pera" console.log(frutas); // ["Fresa", "Manzana", "Uva", "Naranja"] // Eliminar el primer elemento const primeraFruta = frutas.shift(); console.log(primeraFruta); // "Fresa" console.log(frutas); // ["Manzana", "Uva", "Naranja"] // Eliminar elementos en cualquier posición const elementosEliminados = frutas.splice(1, 1); // Elimina 1 elemento desde la posición 1 console.log(elementosEliminados); // ["Uva"] console.log(frutas); // ["Manzana", "Naranja"] // Añadir elementos en cualquier posición frutas.splice(1, 0, "Kiwi", "Piña"); // Inserta en posición 1, sin eliminar nada console.log(frutas); // ["Manzana", "Kiwi", "Piña", "Naranja"] Métodos Importantes de Arrays Concatenación const array1 = [1, 2, 3]; const array2 = [4, 5, 6]; const combinado = array1.concat(array2); console.log(combinado); // [1, 2, 3, 4, 5, 6] // Alternativa usando el operador spread (...) const combinadoSpread = [...array1, ...array2]; console.log(combinadoSpread); // [1, 2, 3, 4, 5, 6] Búsqueda const numeros = [10, 20, 30, 40, 50]; // indexOf - encuentra la primera aparición (devuelve -1 si no existe) console.log(numeros.indexOf(30)); // 2 console.log(numeros.indexOf(60)); // -1 // includes - devuelve true o false console.log(numeros.includes(20)); // true console.log(numeros.includes(60)); // false // find - encuentra el primer elemento que cumple la condición const encontrado = numeros.find(numero => numero > 25); console.log(encontrado); // 30 // findIndex - encuentra el índice del primer elemento que cumple la condición const indiceEncontrado = numeros.findIndex(numero => numero > 25); console.log(indiceEncontrado); // 2 Transformación const numeros = [1, 2, 3, 4, 5]; // map - crea un nuevo array con el resultado de una función aplicada a cada elemento const cuadrados = numeros.map(numero => numero * numero); console.log(cuadrados); // [1, 4, 9, 16, 25] // filter - crea un nuevo array con elementos que cumplen una condición const pares = numeros.filter(numero => numero % 2 === 0); console.log(pares); // [2, 4] // reduce - acumula todos los valores en un solo resultado const suma = numeros.reduce((acumulador, valorActual) => acumulador + valorActual, 0); console.log(suma); // 15 // sort - ordena el array (modifica el original) const desordenados = [5, 2, 8, 1, 4]; desordenados.sort((a, b) => a - b); // Ordenamiento numérico ascendente console.log(desordenados); // [1, 2, 4, 5, 8] // reverse - invierte el orden de los elementos numeros.reverse(); console.log(numeros); // [5, 4, 3, 2, 1] Iteración const frutas = ["Manzana", "Plátano", "Naranja"]; // forEach - ejecuta una función para cada elemento frutas.forEach((fruta, indice) => { console.log(`${indice}: ${fruta}`); }); // every - comprueba si todos los elementos cumplen una condición const todosPositivos = numeros.every(numero => numero > 0); console.log(todosPositivos); // true // some - comprueba si al menos un elemento cumple una condición const algunoMayorQue4 = numeros.some(numero => numero > 4); console.log(algunoMayorQue4); // true Arrays Multidimensionales // Array bidimensional (matriz) const matriz = [ [1, 2, 3], [4, 5, 6], [7, 8, 9] ]; // Acceso a elementos console.log(matriz[0][1]); // 2 console.log(matriz[2][0]); // 7 // Recorrer una matriz for (let i = 0; i < matriz.length; i++) { for (let j = 0; j < matriz[i].length; j++) { console.log(`matriz[${i}][${j}] = ${matriz[i][j]}`); } } Métodos de Arrays Avanzados const datos = [1, 2, 3, 4, 5]; // flat - aplana arrays anidados const anidados = [1, [2, 3], [4, [5, 6]]]; console.log(anidados.flat()); // [1, 2, 3, 4, [5, 6]] console.log(anidados.flat(2)); // [1, 2, 3, 4, 5, 6] // flatMap - combina map y flat const combinado = datos.flatMap(num => [num, num * 2]); console.log(combinado); // [1, 2, 2, 4, 3, 6, 4, 8, 5, 10] // from - crea un array a partir de un iterable const cadena = "hola"; console.log(Array.from(cadena)); // ["h", "o", "l", "a"] // Array.of - crea un array con los argumentos proporcionados console.log(Array.of(1, 2, 3, 4)); // [1, 2, 3, 4] // fill - rellena todos los elementos del array con un valor estático const relleno = new Array(5).fill(0); console.log(relleno); // [0, 0, 0, 0, 0] // slice - extrae una sección del array (sin modificar el original) const original = [1, 2, 3, 4, 5]; const seccion = original.slice(1, 4); console.log(seccion); // [2, 3, 4] Desestructuración de Arrays const valores = [10, 20, 30, 40, 50]; // Desestructuración básica const [primero, segundo, ...resto] = valores; console.log(primero); // 10 console.log(segundo); // 20 console.log(resto); // [30, 40, 50] // Saltar elementos const [a, , c] = valores; console.log(a); // 10 console.log(c); // 30 // Valores por defecto const [p = 0, q = 0, r = 0] = [5, 10]; console.log(p); // 5 console.log(q); // 10 console.log(r); // 0 (valor por defecto) // Intercambio de variables let x = 1; let y = 2; [x, y] = [y, x]; console.log(x); // 2 console.log(y); // 1 Métodos de Conversión de Arrays const numeros = [1, 2, 3, 4, 5]; // join - convierte un array en una cadena const cadena = numeros.join('-'); console.log(cadena); // "1-2-3-4-5" // toString - convierte un array en una cadena (separada por comas) console.log(numeros.toString()); // "1,2,3,4,5" // Array a Set (elimina duplicados) const conDuplicados = [1, 2, 2, 3, 4, 4, 5]; const sinDuplicados = [...new Set(conDuplicados)]; console.log(sinDuplicados); // [1, 2, 3, 4, 5] Array.prototype.entries(), keys() y values() const frutas = ["Manzana", "Banana", "Cereza"]; // entries() - devuelve pares [índice, valor] const entradas = frutas.entries(); for (const [indice, valor] of entradas) { console.log(`${indice}: ${valor}`); } // keys() - devuelve los índices const indices = frutas.keys(); for (const indice of indices) { console.log(indice); // 0, 1, 2 } // values() - devuelve los valores const valores = frutas.values(); for (const valor of valores) { console.log(valor); // "Manzana", "Banana", "Cereza" } Trucos Útiles con Arrays // Eliminar duplicados const conDuplicados = [1, 2, 2, 3, 1, 4, 5, 5]; const unicos = [...new Set(conDuplicados)]; console.log(unicos); // [1, 2, 3, 4, 5] // Encontrar el máximo o mínimo const valores = [5, 12, 8, 130, 44]; console.log(Math.max(...valores)); // 130 console.log(Math.min(...valores)); // 5 // Comprobar si es un array console.log(Array.isArray(valores)); // true console.log(Array.isArray("no soy un array")); // false // Crear un array con números secuenciales const secuencia = Array.from({ length: 5 }, (_, i) => i + 1); console.log(secuencia); // [1, 2, 3, 4, 5] // Aplanar un array multidimensional (antes de ES2019) const aplanarRecursivo = (arr) => { return arr.reduce((acc, val) => Array.isArray(val) ? acc.concat(aplanarRecursivo(val)) : acc.concat(val), []); }; console.log(aplanarRecursivo([1, [2, [3, 4]], 5])); // [1, 2, 3, 4, 5]