
GUÍA COMPLETA PARA ENTREVISTAS DE JAVASCRIPT EN 2025
Introducción a la Preparación de Entrevistas de JavaScript
JavaScript sigue siendo un pilar fundamental en el desarrollo web en 2025, y dominar sus conceptos es esencial para destacar en entrevistas técnicas. Esta guía, diseñada para programadores con conocimientos básicos de la web, HTML, CSS y JavaScript (especialmente ES6+), cubre los temas más frecuentes en entrevistas técnicas. A través de explicaciones claras y ejemplos prácticos, aprenderás sobre variables, arrays, funciones, programación asíncrona y conceptos avanzados como closures y prototipos. Aunque no sustituye un aprendizaje profundo, esta guía actúa como un resumen práctico para entrevistas que te ayudará a consolidar tus habilidades y enfrentar preguntas comunes con confianza.
JavaScript Básico
Comencemos con los fundamentos que todo desarrollador de JavaScript debe conocer.
Variables en JavaScript
Las variables son la base de cualquier lenguaje de programación, permitiendo almacenar valores como números, cadenas y más. JavaScript es un lenguaje de tipado dinámico, lo que significa que no necesitas especificar el tipo de variable al declararla. Existen tres formas principales de declarar variables: var
, let
y const
. Cada una tiene características distintas:
var
: Permite redeclaración y actualización, con alcance global o de función.let
: No permite redeclaración, pero sí actualización, con alcance de bloque.const
: No permite redeclaración ni actualización, con alcance de bloque. Debe inicializarse al declararse.
var a = 3;
var a = 4; // Válido: redeclaración
console.log(a); // 4
let b = 3;
let b = 4; // Error: no se puede redeclarar
b = 4; // Válido: actualización
console.log(b); // 4
const c = 3;
const c = 4; // Error: no se puede redeclarar
c = 4; // Error: no se puede actualizar
Un caso interesante es intentar declarar una constante sin inicializarla:
const d; // Error: const debe inicializarse
Operadores de Comparación: == vs ===
En JavaScript, comparar valores puede hacerse con ==
(compara solo el valor) o ===
(compara valor y tipo). Este último es más estricto y recomendado para evitar errores inesperados.
let a = 5; // Número
let b = "5"; // Cadena
console.log(a == b); // true (solo compara valor)
console.log(a === b); // false (compara valor y tipo)
El operador ===
es preferido en entrevistas porque garantiza una comparación más precisa, evitando conversiones implícitas.
Arrays en JavaScript
Los arrays son estructuras para almacenar múltiples valores, como números, cadenas o incluso otros arrays. Son ideales para manejar colecciones de datos.
let a = 4;
const b = 5;
var c = "hello";
const array = [a, b, c]; // [4, 5, 'hello']
// O directamente:
const arr = [4, 5, "hello"];
Los arrays en JavaScript son dinámicos y ofrecen métodos útiles para manipular datos, como map
, filter
y forEach
, que veremos a continuación.
Métodos de Arrays en JavaScript
Los métodos de arrays son herramientas esenciales para trabajar con colecciones de datos. Aquí exploramos los más comunes en entrevistas: map
, filter
y forEach
.
Método map
El método map
crea un nuevo array aplicando una función a cada elemento del array original, sin modificarlo. Es ideal para transformar datos.
const a = [1, 2, 3, 4, 5];
const d = a.map((item) => item * 2);
console.log(d); // [2, 4, 6, 8, 10]
console.log(a); // [1, 2, 3, 4, 5] (array original intacto)
Método filter
El método filter
genera un nuevo array con los elementos que cumplen una condición específica, útil para seleccionar subconjuntos de datos.
const words = ["react", "script", "interview", "style", "javascript"];
const ans = words.filter((word) => word.length > 6);
console.log(ans); // ['interview', 'javascript']
Alternativamente, puedes lograr lo mismo sin filter
, usando un bucle:
let newArr = [];
for (let i = 0; i < words.length; i++) {
if (words[i].length > 6) {
newArr.push(words[i]);
}
}
console.log(newArr); // ['interview', 'javascript']
Método forEach
A diferencia de map
, forEach
no retorna un nuevo array, sino que ejecuta una función para cada elemento. Es útil para realizar acciones sin necesidad de un resultado.
let arr = [1, 2, 3, 4, 5, 6, 7];
arr.forEach((num) => {
if (num % 2 === 0) {
console.log(num * 2);
}
}); // Imprime: 4, 8, 12
console.log(arr); // [1, 2, 3, 4, 5, 6, 7] (array original intacto)
A diferencia de map
, forEach
no permite encadenamiento de métodos, y su retorno es undefined
.
Programación Funcional en JavaScript
Las funciones son bloques de código reutilizables que pueden aceptar argumentos y devolver valores. En JavaScript, puedes declararlas de dos formas principales:
function a() {
console.log("Función normal");
}
const b = () => {
console.log("Función flecha");
};
Las funciones flecha son más concisas y tienen diferencias en el manejo de this
, que veremos más adelante.
Ámbito (Scope) en JavaScript
El ámbito determina dónde son accesibles las variables. Hay tres tipos principales:
- Global: Variables declaradas fuera de cualquier función, accesibles en todo el programa.
- Función: Variables declaradas dentro de una función, accesibles solo dentro de ella.
- Bloque: Variables declaradas con
let
oconst
dentro de un bloque{}
(como un bucle o condicional), accesibles solo en ese bloque.
var a = 5; // Global
function adder() {
let b = 7; // Función
console.log(a + b); // 12
}
adder();
console.log(b); // Error: b no está definido
{
const c = 10; // Bloque
console.log(c); // 10
}
console.log(c); // Error: c no está definido
Closures en JavaScript
Un closure es una función que recuerda las variables de su entorno léxico, incluso después de que la función externa haya terminado de ejecutarse. Es un concepto clave en entrevistas.
const greet = () => {
const prefix = "Sr";
return (name) => {
console.log(`${prefix} ${name}, ¡bienvenido!`);
};
};
console.log(greet()("Juan")); // Sr Juan, ¡bienvenido!
En este ejemplo, la función interna recuerda prefix
aunque greet
ya se ejecutó. Esto se debe al entorno léxico.
Otro ejemplo práctico:
function x() {
var a = 7;
function y() {
console.log(a);
}
return y;
}
const z = x();
z(); // 7
Ventajas de los Closures
- Currying: Permite crear funciones que aceptan argumentos de forma parcial.
let add = (x) => (y) => x + y;
let addByTwo = add(2);
console.log(addByTwo(3)); // 5
- Encapsulación: Oculta variables para evitar accesos no deseados.
function Counter() {
var count = 0;
this.incrementCount = function () {
count++;
console.log(count);
};
}
const adder = new Counter();
adder.incrementCount(); // 1
console.log(count); // Error: count no está definido
Desventajas de los Closures
Los closures pueden consumir memoria si las variables cerradas no se liberan, ya que no son recolectadas por el garbage collector mientras la función interna las referencie.
Hoisting en JavaScript
El hoisting es el comportamiento de JavaScript de mover las declaraciones al inicio del ámbito. Sin embargo, el comportamiento varía según el tipo de variable:
var
: Se eleva e inicializa conundefined
.let
yconst
: Se elevan, pero no se inicializan, causando un error si se acceden antes de la declaración.- Funciones: Se elevan completas, incluyendo su definición.
console.log(num); // undefined
var num = 10;
console.log(numLet); // Error: no inicializado
let numLet = 10;
sayHello(); // Hola
function sayHello() {
console.log("Hola");
}
Objetos en JavaScript
Los objetos almacenan datos en pares clave-valor, permitiendo estructuras más complejas que los arrays.
const developer = {
name: "Ana",
age: 25,
};
El Contexto de this
El keyword this
en JavaScript se refiere al contexto en el que se ejecuta una función, y su valor depende de cómo se invoca. Por ejemplo:
console.log(this); // Window (en un navegador)
const obj = {
bool: true,
myFunc: function () {
console.log(this);
},
};
obj.myFunc(); // { bool: true, myFunc: [Function] }
En el caso anterior, this
apunta a obj
debido a la vinculación implícita. Sin embargo, si llamas la función sin contexto:
const myFunc = obj.myFunc;
myFunc(); // Window
La vinculación explícita, usando métodos como call
, permite forzar el valor de this
:
const student_1 = {
name: "Ana",
displayName: function () {
console.log(this.name);
},
};
const student_2 = { name: "Luis" };
student_1.displayName.call(student_2); // Luis
Las funciones flecha, sin embargo, no tienen su propio this
, heredando el del ámbito léxico:
const obj = {
name: "Ana",
displayName: () => {
console.log(this.name);
},
};
obj.displayName(); // undefined (this es Window)
Prototipos e Herencia Prototípica
Cada objeto o función en JavaScript tiene un prototipo, un objeto que proporciona propiedades y métodos heredados. El prototipo se accede mediante __proto__
o Object.getPrototypeOf
.
let arr = ["Ana", "Luis"];
console.log(arr.__proto__ === Array.prototype); // true
console.log(arr.__proto__.__proto__ === Object.prototype); // true
console.log(arr.__proto__.__proto__.__proto__); // null
La herencia prototípica permite que un objeto acceda a las propiedades de otro a través de la cadena de prototipos:
let object = {
name: "Ana",
city: "Madrid",
getIntro: function () {
console.log(`${this.name}, ${this.city}`);
},
};
let object2 = { name: "Luis" };
Object.setPrototypeOf(object2, object);
console.log(object2.city); // Madrid
object2.getIntro(); // Luis, Madrid
JavaScript Asíncrono
JavaScript es de un solo hilo, procesando una tarea a la vez. Para manejar operaciones que toman tiempo, como solicitudes a servidores, se usa programación asíncrona.
Event Loop
El event loop es el mecanismo que permite a JavaScript manejar tareas asíncronas. Las tareas se dividen en la pila de ejecución (call stack) y la cola de tareas (task queue). Cuando la pila está vacía, el event loop toma tareas de la cola y las ejecuta.
Temporizadores: setTimeout, setInterval, clearInterval
Los temporizadores permiten programar la ejecución de código:
setTimeout
: Ejecuta una función tras un retraso.setInterval
: Ejecuta una función repetidamente en intervalos.clearInterval
: Detiene unsetInterval
.
setTimeout(() => {
console.log("Ejecutado tras 2 segundos");
}, 2000);
const timer = setInterval(() => {
console.log("Me repito cada 2 segundos");
}, 2000);
clearInterval(timer); // Detiene el intervalo
Un ejemplo común en entrevistas:
console.log("Hola");
setTimeout(() => {
console.log("encantador");
}, 0);
console.log("lector");
// Salida: Hola, lector, encantador
Aunque el retraso de setTimeout
es 0, la función se ejecuta después porque se coloca en la cola de tareas.
Promesas en JavaScript
Las promesas manejan operaciones asíncronas, representando un valor que puede estar disponible ahora, en el futuro o nunca. Una promesa tiene tres estados: pendiente, cumplida o rechazada.
const promise = new Promise((resolve, reject) => {
let value = true;
if (value) {
resolve("Valor es verdadero");
} else {
reject("Error: valor es falso");
}
});
promise
.then((result) => console.log(result)) // Valor es verdadero
.catch((err) => console.log(err));
Con async/await
, el código es más legible:
async function asyncCall() {
const result = await promise;
console.log(result); // Valor es verdadero
}
asyncCall();
Conceptos Avanzados de JavaScript
Polyfills
Un polyfill es código que implementa funcionalidades modernas en navegadores antiguos. Por ejemplo, un polyfill para map
:
Array.prototype.myMap = function (cb) {
let arr = [];
for (let i = 0; i < this.length; i++) {
arr.push(cb(this[i], i, this));
}
return arr;
};
const arr = [1, 2, 3];
console.log(arr.myMap((a) => a * 2)); // [2, 4, 6]
Async y Defer
Los atributos async
y defer
controlan cómo se cargan los scripts en una página web:
- async: Carga el script asíncronamente, ejecutándolo tan pronto como esté disponible, sin garantizar el orden.
- defer: Carga el script asíncronamente, pero lo ejecuta después de que el DOM esté completamente parseado, respetando el orden de los scripts.
<script async src="script1.js"></script>
<script defer src="script2.js"></script>
Usa defer
para scripts dependientes entre sí y async
para scripts independientes.
Debouncing
El debouncing limita la frecuencia de ejecución de una función, útil en eventos como la escritura en un campo de búsqueda.
const getData = (e) => console.log(e.target.value);
const inputField = document.getElementById("text");
const debounce = (fn, delay) => {
let timer;
return function () {
clearTimeout(timer);
timer = setTimeout(() => fn.apply(this, arguments), delay);
};
};
inputField.addEventListener("keyup", debounce(getData, 300));
Throttling
El throttling asegura que una función se ejecute solo una vez en un intervalo de tiempo, útil para eventos como el redimensionamiento de ventanas.
const expensive = () => console.log("Función costosa");
const throttle = (fn, limit) => {
let flag = true;
return function () {
if (flag) {
fn.apply(this, arguments);
flag = false;
setTimeout(() => (flag = true), limit);
}
};
};
const func = throttle(expensive, 2000);
window.addEventListener("resize", func);
La diferencia entre debouncing y throttling radica en que el primero espera un tiempo entre eventos, mientras que el segundo garantiza una ejecución cada cierto intervalo.
Almacenamiento en JavaScript
JavaScript ofrece dos mecanismos principales para almacenar datos en el navegador:
- localStorage: Persiste los datos incluso después de cerrar el navegador.
- sessionStorage: Los datos se eliminan al cerrar la pestaña.
// Guardar
localStorage.setItem("clave", "valor");
// Obtener
let data = localStorage.getItem("clave"); // valor
// Eliminar
localStorage.removeItem("clave");
// Igual para sessionStorage
Conclusiones
Prepararse para una entrevista de JavaScript en 2025 requiere un dominio sólido de conceptos fundamentales y avanzados. Esta guía ha cubierto variables, arrays, funciones, closures, prototipos, programación asíncrona y técnicas como debouncing y throttling. Practicar con ejemplos de código y comprender cómo funcionan mecanismos como el event loop o las promesas te dará una ventaja competitiva. Dedica tiempo a resolver problemas prácticos y experimenta con los ejemplos proporcionados para reforzar tu aprendizaje. Con esta preparación, estarás listo para destacar en tu próxima entrevista técnica.