⚡
Intermedio
15 min lecturaPreguntas de Entrevista JavaScript
Preguntas esenciales de JavaScript para entrevistas
Preguntas Esenciales de Entrevista JavaScript
Domina los conceptos fundamentales y avanzados de JavaScript necesarios para entrevistas técnicas.
1. Explica Hoisting en JavaScript
Hoisting es el comportamiento de JavaScript de mover declaraciones al inicio de su scope:
// Hoisting de variables
console.log(x); // undefined (no error)
var x = 5;
// Equivalente a:
var x;
console.log(x);
x = 5;
// let y const NO se elevan de la misma manera
console.log(y); // ReferenceError: Cannot access before initialization
let y = 10;
// Hoisting de funciones
sayHello(); // "Hola!" - funciona
function sayHello() {
console.log("Hola!");
}
// Expresiones de función NO se elevan
greet(); // TypeError: greet is not a function
var greet = function() {
console.log("Saludos!");
};
2. ¿Cuál es la Diferencia Entre var, let y const?
// var - function scope, hoisting
function example() {
var x = 1;
if (true) {
var x = 2; // Misma variable!
console.log(x); // 2
}
console.log(x); // 2
}
// let - block scope, no hoisting
function example2() {
let x = 1;
if (true) {
let x = 2; // Variable diferente!
console.log(x); // 2
}
console.log(x); // 1
}
// const - block scope, inmutable (referencia)
const obj = { name: "Juan" };
obj.name = "Pedro"; // OK - modificar propiedades
obj = {}; // Error - no se puede reasignar
const arr = [1, 2, 3];
arr.push(4); // OK
arr = []; // Error
3. Explica Closures
Un closure es una función que tiene acceso a variables de su scope externo:
// Closure básico
function createCounter() {
let count = 0;
return {
increment() {
count++;
return count;
},
decrement() {
count--;
return count;
},
getCount() {
return count;
}
};
}
const counter = createCounter();
console.log(counter.increment()); // 1
console.log(counter.increment()); // 2
console.log(counter.getCount()); // 2
// Closure en loop (problema común)
// ❌ Incorrecto
for (var i = 0; i < 3; i++) {
setTimeout(() => console.log(i), 100);
}
// Output: 3, 3, 3
// ✅ Correcto
for (let i = 0; i < 3; i++) {
setTimeout(() => console.log(i), 100);
}
// Output: 0, 1, 2
4. ¿Qué es el Event Loop?
console.log('1');
setTimeout(() => {
console.log('2');
}, 0);
Promise.resolve().then(() => {
console.log('3');
});
console.log('4');
// Output: 1, 4, 3, 2
// Call Stack → Microtasks (Promises) → Macrotasks (setTimeout)
Orden de ejecución:
- Call Stack (código síncrono)
- Microtasks (Promises, queueMicrotask)
- Macrotasks (setTimeout, setInterval)
5. Explica Promesas y Async/Await
// Promesa básica
const fetchData = () => {
return new Promise((resolve, reject) => {
setTimeout(() => {
const data = { user: "Juan" };
resolve(data);
// reject(new Error("Error"));
}, 1000);
});
};
// Usando .then()
fetchData()
.then(data => console.log(data))
.catch(error => console.error(error))
.finally(() => console.log("Completado"));
// Usando async/await
async function getData() {
try {
const data = await fetchData();
console.log(data);
} catch (error) {
console.error(error);
} finally {
console.log("Completado");
}
}
// Promesas en paralelo
const urls = ['url1', 'url2', 'url3'];
// Esperar todas
const results = await Promise.all(
urls.map(url => fetch(url))
);
// Primera en completar
const first = await Promise.race(
urls.map(url => fetch(url))
);
// Todas completadas (fulfilled o rejected)
const all = await Promise.allSettled(
urls.map(url => fetch(url))
);
6. ¿Qué es 'this' y Cómo Funciona?
// Contexto global
console.log(this); // window (browser) o global (Node.js)
// Método de objeto
const obj = {
name: "Juan",
greet() {
console.log(`Hola, ${this.name}`);
}
};
obj.greet(); // "Hola, Juan"
// Función regular vs Arrow Function
const person = {
name: "Juan",
regularFunction: function() {
console.log(this.name); // "Juan"
},
arrowFunction: () => {
console.log(this.name); // undefined (hereda this del scope externo)
}
};
// call, apply, bind
function greet(greeting) {
console.log(`${greeting}, ${this.name}`);
}
const user = { name: "Juan" };
greet.call(user, "Hola"); // "Hola, Juan"
greet.apply(user, ["Hola"]); // "Hola, Juan"
const boundGreet = greet.bind(user);
boundGreet("Hola"); // "Hola, Juan"
7. Explica Prototype y Herencia
// Constructor function
function Person(name, age) {
this.name = name;
this.age = age;
}
Person.prototype.greet = function() {
console.log(`Hola, soy ${this.name}`);
};
const john = new Person("John", 30);
john.greet(); // "Hola, soy John"
// ES6 Classes (sintaxis más limpia)
class Animal {
constructor(name) {
this.name = name;
}
speak() {
console.log(`${this.name} hace un sonido`);
}
}
class Dog extends Animal {
constructor(name, breed) {
super(name);
this.breed = breed;
}
speak() {
console.log(`${this.name} ladra`);
}
}
const dog = new Dog("Rex", "Labrador");
dog.speak(); // "Rex ladra"
8. ¿Qué es Destructuring?
// Array destructuring
const arr = [1, 2, 3, 4, 5];
const [first, second, ...rest] = arr;
console.log(first, second, rest); // 1, 2, [3, 4, 5]
// Object destructuring
const user = {
name: "Juan",
age: 30,
email: "juan@example.com"
};
const { name, age, email: correo } = user;
console.log(name, age, correo); // Juan, 30, juan@example.com
// Valores por defecto
const { name, country = "España" } = user;
// Nested destructuring
const data = {
user: {
profile: {
name: "Juan"
}
}
};
const { user: { profile: { name: userName } } } = data;
console.log(userName); // "Juan"
// En parámetros de función
function greet({ name, age }) {
console.log(`Hola ${name}, tienes ${age} años`);
}
greet({ name: "Juan", age: 30 });
9. Explica Map, Filter y Reduce
const numbers = [1, 2, 3, 4, 5];
// Map - transforma cada elemento
const doubled = numbers.map(n => n * 2);
console.log(doubled); // [2, 4, 6, 8, 10]
// Filter - filtra elementos
const evens = numbers.filter(n => n % 2 === 0);
console.log(evens); // [2, 4]
// Reduce - reduce a un valor único
const sum = numbers.reduce((acc, n) => acc + n, 0);
console.log(sum); // 15
// Ejemplo complejo: agrupar por propiedad
const users = [
{ name: "Juan", age: 25 },
{ name: "Ana", age: 30 },
{ name: "Pedro", age: 25 }
];
const groupedByAge = users.reduce((acc, user) => {
const age = user.age;
if (!acc[age]) acc[age] = [];
acc[age].push(user);
return acc;
}, {});
console.log(groupedByAge);
// { 25: [{name: "Juan", age: 25}, {name: "Pedro", age: 25}],
// 30: [{name: "Ana", age: 30}] }
10. ¿Qué es el Spread Operator y Rest Parameters?
// Spread operator (...)
const arr1 = [1, 2, 3];
const arr2 = [4, 5, 6];
const combined = [...arr1, ...arr2]; // [1, 2, 3, 4, 5, 6]
// Copiar arrays
const copy = [...arr1]; // [1, 2, 3]
// Spread en objetos
const obj1 = { a: 1, b: 2 };
const obj2 = { c: 3, d: 4 };
const merged = { ...obj1, ...obj2 }; // { a: 1, b: 2, c: 3, d: 4 }
// Sobrescribir propiedades
const user = { name: "Juan", age: 30 };
const updated = { ...user, age: 31 }; // { name: "Juan", age: 31 }
// Rest parameters
function sum(...numbers) {
return numbers.reduce((acc, n) => acc + n, 0);
}
console.log(sum(1, 2, 3, 4, 5)); // 15
// Con destructuring
const [first, ...rest] = [1, 2, 3, 4, 5];
console.log(first, rest); // 1, [2, 3, 4, 5]
Mejores Prácticas de JavaScript
- ✓ Usa
constpor defecto,letcuando sea necesario, evitavar - ✓ Usa arrow functions para callbacks cortos
- ✓ Prefiere async/await sobre promesas encadenadas
- ✓ Usa destructuring para código más limpio
- ✓ Aprovecha métodos de array como map, filter, reduce
- ✓ Maneja errores apropiadamente con try/catch
- ✓ Evita modificar el prototype de objetos nativos