Top 10 Preguntas Esenciales de JavaScript
Las 10 Preguntas Más Importantes de JavaScript
Section titled “Las 10 Preguntas Más Importantes de JavaScript”Estas son las preguntas que siempre aparecen en entrevistas técnicas de JavaScript.
1. ¿Cuál es la diferencia entre var, let y const?
Section titled “1. ¿Cuál es la diferencia entre var, let y const?”Introducción: Pregunta fundamental en cualquier entrevista de JavaScript. Demuestra comprensión del scope y buenas prácticas modernas.
Definición profesional:
Son las tres formas de declarar variables en JavaScript. var tiene scope de función, mientras que let y const (ES6+) tienen scope de bloque. const no permite reasignación.
Explicación sencilla:
- var: La forma antigua, puede causar bugs por su scope amplio
- let: Para variables que cambiarán de valor
- const: Para variables que no cambiarán (constantes)
Funcionamiento básico:
| Característica | var | let | const |
|---|---|---|---|
| Scope | Función | Bloque | Bloque |
| Hoisting | Sí (undefined) | Sí (TDZ) | Sí (TDZ) |
| Reasignación | ✅ | ✅ | ❌ |
| Redeclaración | ✅ | ❌ | ❌ |
Ejemplo práctico:
// var - scope de función (EVITAR)function ejemplo() {if (true) { var x = 10;}console.log(x); // 10 - accesible fuera del if ⚠️}
// let - scope de bloquefunction ejemplo2() {if (true) { let y = 20;}console.log(y); // ReferenceError ✅}
// const - no se puede reasignarconst PI = 3.14159;// PI = 3; // TypeError
// PERO objetos/arrays const SÍ pueden modificarse internamenteconst usuario = { nombre: 'Juan' };usuario.nombre = 'Ana'; // ✅ Esto sí funcionaCasos de uso reales:
- const: Por defecto para todo (objetos, funciones, imports)
- let: Contadores, acumuladores, valores que cambian en loops
- var: Nunca en código moderno
Cómo responder en entrevista:
“La diferencia principal es el scope:
vartiene scope de función mientras queletyconsttienen scope de bloque. Además,constno permite reasignación. En código moderno, la mejor práctica es usarconstpor defecto yletsolo cuando necesitamos reasignar.vardebe evitarse porque puede causar bugs difíciles de detectar debido a su scope amplio y hoisting.”
2. ¿Qué es un Closure?
Section titled “2. ¿Qué es un Closure?”Introducción: Concepto fundamental de JavaScript. Los closures están en todas partes: callbacks, event handlers, módulos.
Definición profesional: Un closure es una función que mantiene acceso a las variables de su ámbito léxico (scope externo), incluso después de que la función externa haya terminado de ejecutarse.
Explicación sencilla: Una función “recuerda” las variables del lugar donde fue creada, aunque se ejecute en otro lugar.
Funcionamiento básico:
- Una función externa define variables
- Una función interna usa esas variables
- La función interna se retorna o pasa como callback
- Las variables “viven” mientras la función interna exista
Ejemplo práctico:
// Closure básico - contador privadofunction crearContador() {let contador = 0; // Variable "privada"
return function() { contador++; return contador;};}
const contador1 = crearContador();console.log(contador1()); // 1console.log(contador1()); // 2console.log(contador1()); // 3
const contador2 = crearContador(); // Nuevo closure, nuevo contadorconsole.log(contador2()); // 1
// Closure en la práctica - factory functionfunction crearSaludo(saludo) {return function(nombre) { return saludo + ', ' + nombre;};}
const saludarES = crearSaludo('Hola');const saludarEN = crearSaludo('Hello');
console.log(saludarES('Juan')); // "Hola, Juan"console.log(saludarEN('John')); // "Hello, John"Casos de uso reales:
- Encapsulación: Variables privadas (como el contador)
- Factory functions: Crear funciones configuradas
- Event handlers: Mantener estado entre eventos
- Callbacks: Acceder a variables del contexto original
Cómo responder en entrevista:
“Un closure es una función que recuerda las variables del scope donde fue creada, incluso cuando se ejecuta fuera de ese scope. Esto ocurre porque JavaScript mantiene una referencia al ámbito léxico de la función. Los closures son útiles para encapsulación, crear funciones factory, y mantener estado en callbacks y event handlers.”
3. ¿Cuál es la diferencia entre == y ===?
Section titled “3. ¿Cuál es la diferencia entre == y ===?”Introducción: Pregunta clásica que evalúa comprensión de coerción de tipos. Errores aquí causan bugs sutiles.
Definición profesional:
== (igualdad abstracta) compara valores realizando coerción de tipos si es necesario. === (igualdad estricta) compara valor Y tipo sin ninguna conversión.
Explicación sencilla:
==pregunta: “¿Son equivalentes?” (convierte tipos para comparar)===pregunta: “¿Son exactamente iguales?” (mismo valor Y mismo tipo)
Funcionamiento básico:
| Comparación | == | === |
|---|---|---|
5 == "5" | true | false |
0 == false | true | false |
null == undefined | true | false |
1 == true | true | false |
Ejemplo práctico:
// == (igualdad débil) - EVITARconsole.log(5 == "5"); // true ⚠️console.log(0 == false); // true ⚠️console.log("" == false); // true ⚠️console.log(null == undefined); // true ⚠️
// === (igualdad estricta) - USAR SIEMPREconsole.log(5 === "5"); // false ✅console.log(0 === false); // false ✅console.log(null === undefined); // false ✅
// Caso especial: NaNconsole.log(NaN === NaN); // false (usar Number.isNaN())
// Objetos: compara referencias, no contenidoconst a = { x: 1 };const b = { x: 1 };console.log(a === b); // false (diferentes objetos)Casos de uso reales:
- Siempre usar
===para evitar bugs de coerción - Excepción:
valor == nullpara verificar null O undefined
Cómo responder en entrevista:
“El operador
==hace coerción de tipos antes de comparar, lo que puede dar resultados inesperados como0 == falsesiendo true. El operador===compara valor y tipo sin conversión. La mejor práctica es siempre usar===para evitar bugs. La única excepción común esx == nullque verifica tanto null como undefined en una sola comparación.”
4. ¿Qué es el Event Loop?
Section titled “4. ¿Qué es el Event Loop?”Introducción: Concepto esencial para entender asincronía en JavaScript. Explica por qué setTimeout(0) no se ejecuta inmediatamente.
Definición profesional: El Event Loop es el mecanismo que permite a JavaScript manejar operaciones asíncronas siendo single-threaded. Coordina la ejecución entre el Call Stack, las Web APIs, y las colas de tareas.
Explicación sencilla: JavaScript ejecuta código línea por línea (Call Stack). Cuando hay algo asíncrono (setTimeout, fetch), lo envía a las Web APIs. Cuando termina, va a una cola. El Event Loop mueve tareas de la cola al Call Stack cuando está vacío.
Funcionamiento básico:
1. Call Stack ejecuta código síncrono2. Operaciones async van a Web APIs3. Cuando terminan, van a la cola: - Microtasks: Promises, queueMicrotask - Macrotasks: setTimeout, setInterval, I/O4. Event Loop: Stack vacío → Microtasks → 1 Macrotask → repetirEjemplo práctico:
console.log('1'); // Síncrono
setTimeout(() => {console.log('2'); // Macrotask}, 0);
Promise.resolve().then(() => {console.log('3'); // Microtask});
console.log('4'); // Síncrono
// Salida: 1, 4, 3, 2// ¿Por qué?// 1. Síncronos primero: 1, 4// 2. Microtasks (Promises): 3// 3. Macrotasks (setTimeout): 2Casos de uso reales:
- Entender por qué
setTimeout(fn, 0)no es inmediato - Debugging de código asíncrono
- Optimizar performance (evitar bloquear el main thread)
- Entender el orden de ejecución de Promises vs callbacks
Cómo responder en entrevista:
“El Event Loop es el mecanismo que permite a JavaScript manejar asincronía siendo single-threaded. Funciona coordinando el Call Stack con las colas de tareas. Primero ejecuta todo el código síncrono, luego procesa todas las microtasks (Promises), y finalmente una macrotask (setTimeout). Por eso un Promise.then() siempre se ejecuta antes que un setTimeout(0).“
5. ¿Cuál es la diferencia entre null y undefined?
Section titled “5. ¿Cuál es la diferencia entre null y undefined?”Introducción: Pregunta frecuente que evalúa comprensión de los valores “vacíos” en JavaScript y cuándo usar cada uno.
Definición profesional:
undefined es el valor por defecto de variables no inicializadas y representa ausencia de valor no intencional. null es un valor asignado explícitamente que representa ausencia intencional de valor.
Explicación sencilla:
- undefined: “No sé qué valor tiene” (JavaScript lo asigna)
- null: “Sé que no tiene valor” (tú lo asignas)
Funcionamiento básico:
| Aspecto | undefined | null |
|---|---|---|
| Significado | Sin valor asignado | Ausencia intencional |
| Quién lo asigna | JavaScript | El programador |
| typeof | ”undefined" | "object” (bug) |
| En JSON | No válido | Válido |
Ejemplo práctico:
// undefined - JavaScript lo asignalet x;console.log(x); // undefined
function foo(param) {console.log(param); // undefined si no se pasa}
const obj = {};console.log(obj.propiedad); // undefined
// null - tú lo asignas intencionalmentelet usuario = null; // "No hay usuario todavía"
function buscarUsuario(id) {const usuario = db.find(id);return usuario || null; // Explícito: no encontrado}
// Comparaciónconsole.log(null == undefined); // true (coerción)console.log(null === undefined); // false (tipos diferentes)
// typeof (bug histórico)console.log(typeof undefined); // "undefined"console.log(typeof null); // "object" ⚠️Casos de uso reales:
- undefined: Parámetros opcionales, propiedades no existentes
- null: Limpiar referencias, indicar “sin valor” explícitamente, respuestas de API
Cómo responder en entrevista:
“La diferencia principal es la intención:
undefinedsignifica que una variable no tiene valor asignado (JavaScript lo pone automáticamente), mientras quenulles un valor que asignamos explícitamente para indicar ‘sin valor’. Un dato curioso es quetypeof nullretorna ‘object’, que es un bug histórico de JavaScript. Para verificar ambos a la vez, podemos usarx == nullque es true para null y undefined.”
6. ¿Qué son las Promises y async/await?
Section titled “6. ¿Qué son las Promises y async/await?”Introducción: Tema esencial de JavaScript moderno. Las Promises y async/await son la base de toda operación asíncrona.
Definición profesional: Una Promise es un objeto que representa el resultado eventual de una operación asíncrona (pendiente, cumplida o rechazada). async/await es sintaxis que permite escribir código asíncrono con apariencia síncrona.
Explicación sencilla:
- Promise: Una “promesa” de que tendrás un valor en el futuro
- async/await: Forma más legible de trabajar con Promises
Funcionamiento básico:
Estados de una Promise:
pending: Esperando resultadofulfilled: Operación exitosa (resolve)rejected: Operación fallida (reject)
Sintaxis:
// Crear Promisenew Promise((resolve, reject) => { ... })
// Consumir Promisepromise.then(resultado => ...).catch(error => ...)
// async/awaitasync function foo() {const resultado = await promise;}Ejemplo práctico:
// Crear una Promisefunction fetchUsuario(id) {return new Promise((resolve, reject) => { setTimeout(() => { if (id > 0) { resolve({ id, nombre: 'Juan' }); } else { reject(new Error('ID inválido')); } }, 1000);});}
// Consumir con .then()/.catch()fetchUsuario(1).then(usuario => console.log(usuario)).catch(error => console.error(error));
// Consumir con async/await (más legible)async function mostrarUsuario() {try { const usuario = await fetchUsuario(1); console.log(usuario);} catch (error) { console.error(error);}}
// Múltiples Promises en paraleloconst [user, posts] = await Promise.all([fetchUsuario(1),fetchPosts(1)]);Casos de uso reales:
- Llamadas a APIs (fetch)
- Operaciones de base de datos
- Lectura de archivos
- Cualquier operación que tome tiempo
Cómo responder en entrevista:
“Una Promise es un objeto que representa un valor futuro con tres estados: pending, fulfilled o rejected. async/await es sintaxis que hace el código asíncrono más legible. Una función async siempre retorna una Promise, y await pausa la ejecución hasta que la Promise se resuelve. Para manejar errores uso try/catch con async/await o .catch() con Promises. Para operaciones en paralelo uso Promise.all().“
7. ¿Qué es el Hoisting?
Section titled “7. ¿Qué es el Hoisting?”Introducción: Concepto que explica comportamientos “extraños” de JavaScript. Entenderlo evita bugs comunes.
Definición profesional: Hoisting es el comportamiento de JavaScript donde las declaraciones de variables y funciones se “mueven” al inicio de su scope durante la fase de compilación, antes de la ejecución del código.
Explicación sencilla: JavaScript “lee” tu código dos veces: primero registra todas las declaraciones, luego ejecuta. Por eso puedes usar una función antes de declararla.
Funcionamiento básico:
| Tipo | Se eleva | Valor inicial |
|---|---|---|
var | ✅ | undefined |
let/const | ✅ | TDZ (error si accedes) |
function | ✅ | La función completa |
class | ✅ | TDZ |
Ejemplo práctico:
// VAR - se eleva con valor undefinedconsole.log(nombre); // undefined (no error)var nombre = "Juan";
// JavaScript lo interpreta así:// var nombre;// console.log(nombre); // undefined// nombre = "Juan";
// LET/CONST - TDZ (Temporal Dead Zone)console.log(edad); // ReferenceError ❌let edad = 25;
// FUNCIONES - se elevan completassaludar(); // "Hola" ✅function saludar() {console.log("Hola");}
// FUNCTION EXPRESSIONS - NO se elevandespedir(); // TypeError ❌var despedir = function() {console.log("Adiós");};Casos de uso reales:
- Entender por qué las funciones pueden llamarse antes de declararse
- Evitar bugs con
var(usarlet/const) - Organizar código: declaraciones arriba, uso abajo
Cómo responder en entrevista:
“Hoisting es el comportamiento donde JavaScript mueve las declaraciones al inicio del scope durante la compilación. Las variables
varse elevan con valorundefined, las funciones declaradas se elevan completas, ylet/constse elevan pero quedan en la Temporal Dead Zone hasta su declaración, causando error si se acceden antes. Por eso es mejor práctica usarlet/consty declarar variables al inicio.”
8. ¿Cuál es la diferencia entre Arrow Functions y funciones normales?
Section titled “8. ¿Cuál es la diferencia entre Arrow Functions y funciones normales?”Introducción:
Pregunta importante sobre ES6. La diferencia clave está en cómo manejan this.
Definición profesional:
Las arrow functions son una sintaxis concisa para funciones que no tienen su propio this, arguments, super, ni pueden usarse como constructores. Heredan this del scope donde fueron definidas (lexical this).
Explicación sencilla:
- Función normal:
thisdepende de CÓMO se llama - Arrow function:
thisdepende de DÓNDE se define
Funcionamiento básico:
| Característica | Función Normal | Arrow Function |
|---|---|---|
| Sintaxis | function() {} | () => {} |
this propio | ✅ | ❌ (hereda) |
arguments | ✅ | ❌ |
Constructor (new) | ✅ | ❌ |
| Métodos de objeto | ✅ | ❌ |
Ejemplo práctico:
// Sintaxisconst sumar = (a, b) => a + b;const cuadrado = x => x * x; // Un parámetro: sin paréntesisconst saludar = () => console.log('Hola');
// DIFERENCIA CLAVE: thisconst objeto = {nombre: 'Juan',
// Función normal - this es el objetosaludar: function() { console.log(this.nombre); // "Juan" ✅},
// Arrow - this es el contexto externo (window/undefined)saludarArrow: () => { console.log(this.nombre); // undefined ❌},
// Caso útil de arrow: callbackssaludarConDelay: function() { setTimeout(() => { console.log(this.nombre); // "Juan" ✅ // Arrow hereda this de saludarConDelay }, 1000);}};Casos de uso reales:
- Arrow: Callbacks, map/filter/reduce, funciones cortas
- Normal: Métodos de objeto, constructores, cuando necesitas
thisdinámico
Cómo responder en entrevista:
“La diferencia principal es el manejo de
this: las funciones normales tienen su propiothisque depende de cómo se llaman, mientras que las arrow functions heredanthisdel scope donde se definen (lexical this). Por eso las arrow functions son ideales para callbacks donde queremos mantener elthisdel contexto, pero no deben usarse como métodos de objeto ni constructores.”
9. ¿Qué es el Spread Operator y Rest Parameters?
Section titled “9. ¿Qué es el Spread Operator y Rest Parameters?”Introducción:
Sintaxis ES6 muy usada. Mismo símbolo (...), pero propósitos opuestos según el contexto.
Definición profesional:
El operador Spread (...) expande un iterable en elementos individuales. Rest Parameters (...) agrupa múltiples argumentos en un array. El contexto determina cuál es cuál.
Explicación sencilla:
- Spread: “Desempacar” - convierte array/objeto en elementos sueltos
- Rest: “Empacar” - convierte elementos sueltos en array
Funcionamiento básico:
| Operador | Contexto | Acción |
|---|---|---|
| Spread | En llamada/literal | Expande |
| Rest | En parámetros/destructuring | Agrupa |
Ejemplo práctico:
// ========== SPREAD - Expandir ==========
// Arraysconst arr1 = [1, 2, 3];const arr2 = [...arr1, 4, 5]; // [1, 2, 3, 4, 5]const copia = [...arr1]; // Copia superficial
// Objetosconst obj1 = { a: 1, b: 2 };const obj2 = { ...obj1, c: 3 }; // { a: 1, b: 2, c: 3 }const merged = { ...obj1, ...obj2 }; // Combinar
// En llamadas a funciónMath.max(...arr1); // 3
// ========== REST - Agrupar ==========
// En parámetros de funciónfunction sumar(...numeros) {return numeros.reduce((a, b) => a + b, 0);}sumar(1, 2, 3, 4); // 10
// En destructuringconst [primero, ...resto] = [1, 2, 3, 4];// primero = 1, resto = [2, 3, 4]
const { nombre, ...otros } = { nombre: 'Juan', edad: 25, ciudad: 'Lima' };// nombre = 'Juan', otros = { edad: 25, ciudad: 'Lima' }Casos de uso reales:
- Spread: Clonar arrays/objetos, combinar, pasar argumentos
- Rest: Funciones con argumentos variables, destructuring parcial
Cómo responder en entrevista:
“Spread y Rest usan la misma sintaxis (
...) pero hacen lo opuesto. Spread expande un array u objeto en elementos individuales, útil para copiar, combinar o pasar argumentos. Rest agrupa múltiples elementos en un array, útil en parámetros de función o destructuring. La diferencia está en el contexto: si está en una expresión es Spread, si está en una declaración de parámetros o destructuring es Rest.”
10. ¿Qué son los métodos de Array más usados?
Section titled “10. ¿Qué son los métodos de Array más usados?”Introducción: Pregunta práctica muy común. Estos métodos son el pan de cada día en JavaScript moderno.
Definición profesional: Son métodos de alto orden (reciben funciones como argumento) que permiten transformar, filtrar y procesar arrays de forma declarativa e inmutable.
Explicación sencilla:
- map: Transforma cada elemento → nuevo array
- filter: Filtra elementos → nuevo array con los que cumplen
- reduce: Acumula todo → un solo valor
- find: Busca → primer elemento que cumple
- some/every: Verifica → true/false
Funcionamiento básico:
| Método | Retorna | Uso |
|---|---|---|
map() | Array transformado | Modificar cada elemento |
filter() | Array filtrado | Seleccionar elementos |
reduce() | Valor único | Acumular, sumar, agrupar |
find() | Elemento o undefined | Buscar uno |
some() | Boolean | ¿Alguno cumple? |
every() | Boolean | ¿Todos cumplen? |
Ejemplo práctico:
const usuarios = [{ nombre: 'Ana', edad: 25, activo: true },{ nombre: 'Juan', edad: 17, activo: false },{ nombre: 'María', edad: 30, activo: true }];
// MAP - obtener solo nombresconst nombres = usuarios.map(u => u.nombre);// ['Ana', 'Juan', 'María']
// FILTER - solo mayores de edadconst mayores = usuarios.filter(u => u.edad >= 18);// [{ nombre: 'Ana', ... }, { nombre: 'María', ... }]
// REDUCE - suma de edadesconst sumaEdades = usuarios.reduce((acc, u) => acc + u.edad, 0);// 72
// FIND - buscar por nombreconst juan = usuarios.find(u => u.nombre === 'Juan');// { nombre: 'Juan', edad: 17, activo: false }
// SOME - ¿hay menores?const hayMenores = usuarios.some(u => u.edad < 18);// true
// EVERY - ¿todos activos?const todosActivos = usuarios.every(u => u.activo);// false
// ENCADENAMIENTO - nombres de usuarios activos mayores de edadconst resultado = usuarios.filter(u => u.activo && u.edad >= 18).map(u => u.nombre);// ['Ana', 'María']Casos de uso reales:
- map: Renderizar listas en React, transformar datos de API
- filter: Búsqueda, filtros de UI
- reduce: Totales, agrupaciones, transformaciones complejas
- find: Buscar usuario por ID, elemento específico
Cómo responder en entrevista:
“Los métodos más usados son map, filter y reduce. Map transforma cada elemento y retorna un nuevo array. Filter retorna un nuevo array solo con elementos que cumplen una condición. Reduce acumula todos los elementos en un solo valor. Todos son inmutables, no modifican el array original. También uso find para buscar un elemento, y some/every para verificar condiciones. Estos métodos se pueden encadenar para operaciones complejas.”