Cómo aprobar una entrevista de JavaScript: las mejores preguntas de nivel avanzado
Una entrevista para un puesto de desarrollador Senior o Middle JavaScript no es solo una verificación de sintaxis. Los entrevistadores quieren ver una comprensión profunda de los mecanismos del lenguaje, especialmente en el entorno Node.js. En este artículo, analizaremos los temas clave que suelen causar dificultades y daremos ejemplos de código que te ayudarán a responder con confianza las preguntas más difíciles.
1. Closures y entorno léxico
La pregunta sobre closures es un clásico. Pero a nivel avanzado, es importante no solo dar una definición, sino mostrar cómo funcionan los closures con let, const y en bucles.
Pregunta: ¿Qué imprime el siguiente código y por qué?
for (var i = 0; i < 3; i++) { setTimeout(() => console.log(i), 100);}// Salida: 3, 3, 3El problema es que var tiene ámbito de función, no de bloque. Cuando se ejecutan los callbacks, el bucle ya ha terminado y i es igual a 3. La solución es usar let (crea un nuevo enlace en cada iteración) o envolver la llamada en un closure:
for (var i = 0; i < 3; i++) { (function(j) { setTimeout(() => console.log(j), 100); })(i);}// Salida: 0, 1, 2En Node.js, los closures se utilizan activamente para crear variables privadas y fábricas de funciones. Por ejemplo, al escribir middleware:
function createLogger(prefix) { return function(message) { console.log(`[${prefix}] ${message}`); };}const infoLog = createLogger('INFO');infoLog('Servidor iniciado'); // [INFO] Servidor iniciado2. Event Loop y microtareas (Microtasks)
Comprender el ciclo de eventos es uno de los principales criterios de evaluación. A los entrevistadores les gusta dar tareas sobre el orden de ejecución del código asíncrono.
Pregunta: ¿En qué orden se ejecutarán los console.log?
console.log('1');
setTimeout(() => console.log('2'), 0);
Promise.resolve().then(() => console.log('3'));
process.nextTick(() => console.log('4'));
console.log('5');
// Salida: 1, 5, 4, 3, 2Análisis:
console.log('1')yconsole.log('5')son síncronos, se ejecutan primero.process.nextTickes una microtarea con la prioridad más alta. Se ejecuta inmediatamente después de completar la fase actual.Promise.thentambién es una microtarea, pero con una prioridad ligeramente menor quenextTick.setTimeout(fn, 0)es una macrotarea, se ejecuta en el siguiente tick del Event Loop.
Para Node.js, es importante recordar process.nextTick y setImmediate. La diferencia es que nextTick se ejecuta antes de cualquier E/S, mientras que setImmediate se ejecuta después.
3. Promesas e iteradores asíncronos (Async/Await)
El nivel avanzado implica la capacidad de trabajar con cadenas de promesas, manejo de errores y ejecución paralela.
Pregunta: ¿Cómo manejar varias solicitudes asíncronas para ejecutarlas en paralelo pero esperar todos los resultados?
const fetchData = (id) => { return new Promise((resolve) => { setTimeout(() => resolve(`Datos para ID: ${id}`), id * 100); });};
async function getAllData() { const ids = [1, 2, 3]; const promises = ids.map(id => fetchData(id)); const results = await Promise.all(promises); console.log(results); // ['Datos para ID: 1', 'Datos para ID: 2', 'Datos para ID: 3']}
getAllData();Matiz importante: Promise.all rechaza toda la promesa ante el primer error. Si necesitas obtener todos los resultados (incluso con errores), usa Promise.allSettled. Este es un tema frecuente en entrevistas en el contexto