Skip to content

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ísticavarletconst
ScopeFunciónBloqueBloque
HoistingSí (undefined)Sí (TDZ)Sí (TDZ)
Reasignación
Redeclaración

Ejemplo práctico:

var vs let vs const
// var - scope de función (EVITAR)
function ejemplo() {
if (true) {
var x = 10;
}
console.log(x); // 10 - accesible fuera del if ⚠️
}
// let - scope de bloque
function ejemplo2() {
if (true) {
let y = 20;
}
console.log(y); // ReferenceError ✅
}
// const - no se puede reasignar
const PI = 3.14159;
// PI = 3; // TypeError
// PERO objetos/arrays const SÍ pueden modificarse internamente
const usuario = { nombre: 'Juan' };
usuario.nombre = 'Ana'; // ✅ Esto sí funciona

Casos 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: var tiene scope de función mientras que let y const tienen scope de bloque. Además, const no permite reasignación. En código moderno, la mejor práctica es usar const por defecto y let solo cuando necesitamos reasignar. var debe evitarse porque puede causar bugs difíciles de detectar debido a su scope amplio y hoisting.”


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:

  1. Una función externa define variables
  2. Una función interna usa esas variables
  3. La función interna se retorna o pasa como callback
  4. Las variables “viven” mientras la función interna exista

Ejemplo práctico:

Closures
// Closure básico - contador privado
function crearContador() {
let contador = 0; // Variable "privada"
return function() {
contador++;
return contador;
};
}
const contador1 = crearContador();
console.log(contador1()); // 1
console.log(contador1()); // 2
console.log(contador1()); // 3
const contador2 = crearContador(); // Nuevo closure, nuevo contador
console.log(contador2()); // 1
// Closure en la práctica - factory function
function 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"truefalse
0 == falsetruefalse
null == undefinedtruefalse
1 == truetruefalse

Ejemplo práctico:

== vs ===
// == (igualdad débil) - EVITAR
console.log(5 == "5"); // true ⚠️
console.log(0 == false); // true ⚠️
console.log("" == false); // true ⚠️
console.log(null == undefined); // true ⚠️
// === (igualdad estricta) - USAR SIEMPRE
console.log(5 === "5"); // false ✅
console.log(0 === false); // false ✅
console.log(null === undefined); // false ✅
// Caso especial: NaN
console.log(NaN === NaN); // false (usar Number.isNaN())
// Objetos: compara referencias, no contenido
const 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 == null para 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 como 0 == false siendo 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 es x == null que verifica tanto null como undefined en una sola comparación.”


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íncrono
2. Operaciones async van a Web APIs
3. Cuando terminan, van a la cola:
- Microtasks: Promises, queueMicrotask
- Macrotasks: setTimeout, setInterval, I/O
4. Event Loop: Stack vacío → Microtasks → 1 Macrotask → repetir

Ejemplo práctico:

Event Loop
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): 2

Casos 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:

Aspectoundefinednull
SignificadoSin valor asignadoAusencia intencional
Quién lo asignaJavaScriptEl programador
typeof”undefined""object” (bug)
En JSONNo válidoVálido

Ejemplo práctico:

null vs undefined
// undefined - JavaScript lo asigna
let 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 intencionalmente
let usuario = null; // "No hay usuario todavía"
function buscarUsuario(id) {
const usuario = db.find(id);
return usuario || null; // Explícito: no encontrado
}
// Comparación
console.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: undefined significa que una variable no tiene valor asignado (JavaScript lo pone automáticamente), mientras que null es un valor que asignamos explícitamente para indicar ‘sin valor’. Un dato curioso es que typeof null retorna ‘object’, que es un bug histórico de JavaScript. Para verificar ambos a la vez, podemos usar x == null que es true para null y undefined.”


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 resultado
  • fulfilled: Operación exitosa (resolve)
  • rejected: Operación fallida (reject)

Sintaxis:

// Crear Promise
new Promise((resolve, reject) => { ... })
// Consumir Promise
promise.then(resultado => ...).catch(error => ...)
// async/await
async function foo() {
const resultado = await promise;
}

Ejemplo práctico:

Promises y async/await
// Crear una Promise
function 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 paralelo
const [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().“


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:

TipoSe elevaValor inicial
varundefined
let/constTDZ (error si accedes)
functionLa función completa
classTDZ

Ejemplo práctico:

Hoisting
// VAR - se eleva con valor undefined
console.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 completas
saludar(); // "Hola" ✅
function saludar() {
console.log("Hola");
}
// FUNCTION EXPRESSIONS - NO se elevan
despedir(); // 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 (usar let/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 var se elevan con valor undefined, las funciones declaradas se elevan completas, y let/const se elevan pero quedan en la Temporal Dead Zone hasta su declaración, causando error si se acceden antes. Por eso es mejor práctica usar let/const y 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: this depende de CÓMO se llama
  • Arrow function: this depende de DÓNDE se define

Funcionamiento básico:

CaracterísticaFunción NormalArrow Function
Sintaxisfunction() {}() => {}
this propio❌ (hereda)
arguments
Constructor (new)
Métodos de objeto

Ejemplo práctico:

Arrow vs Normal Functions
// Sintaxis
const sumar = (a, b) => a + b;
const cuadrado = x => x * x; // Un parámetro: sin paréntesis
const saludar = () => console.log('Hola');
// DIFERENCIA CLAVE: this
const objeto = {
nombre: 'Juan',
// Función normal - this es el objeto
saludar: function() {
console.log(this.nombre); // "Juan" ✅
},
// Arrow - this es el contexto externo (window/undefined)
saludarArrow: () => {
console.log(this.nombre); // undefined ❌
},
// Caso útil de arrow: callbacks
saludarConDelay: 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 this dinámico

Cómo responder en entrevista:

“La diferencia principal es el manejo de this: las funciones normales tienen su propio this que depende de cómo se llaman, mientras que las arrow functions heredan this del scope donde se definen (lexical this). Por eso las arrow functions son ideales para callbacks donde queremos mantener el this del 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:

OperadorContextoAcción
SpreadEn llamada/literalExpande
RestEn parámetros/destructuringAgrupa

Ejemplo práctico:

Spread y Rest
// ========== SPREAD - Expandir ==========
// Arrays
const arr1 = [1, 2, 3];
const arr2 = [...arr1, 4, 5]; // [1, 2, 3, 4, 5]
const copia = [...arr1]; // Copia superficial
// Objetos
const 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ón
Math.max(...arr1); // 3
// ========== REST - Agrupar ==========
// En parámetros de función
function sumar(...numeros) {
return numeros.reduce((a, b) => a + b, 0);
}
sumar(1, 2, 3, 4); // 10
// En destructuring
const [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étodoRetornaUso
map()Array transformadoModificar cada elemento
filter()Array filtradoSeleccionar elementos
reduce()Valor únicoAcumular, sumar, agrupar
find()Elemento o undefinedBuscar uno
some()Boolean¿Alguno cumple?
every()Boolean¿Todos cumplen?

Ejemplo práctico:

Métodos de Array
const usuarios = [
{ nombre: 'Ana', edad: 25, activo: true },
{ nombre: 'Juan', edad: 17, activo: false },
{ nombre: 'María', edad: 30, activo: true }
];
// MAP - obtener solo nombres
const nombres = usuarios.map(u => u.nombre);
// ['Ana', 'Juan', 'María']
// FILTER - solo mayores de edad
const mayores = usuarios.filter(u => u.edad >= 18);
// [{ nombre: 'Ana', ... }, { nombre: 'María', ... }]
// REDUCE - suma de edades
const sumaEdades = usuarios.reduce((acc, u) => acc + u.edad, 0);
// 72
// FIND - buscar por nombre
const 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 edad
const 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.”


🐝