Experienced JavaScript Interview Questions
What is the this keyword in JavaScript?
this refers to the object that is calling the function.
- In an object method,
thisis the object before the dot. - In a normal function,
thisisundefined(strict mode) or the global object. - In an arrow function,
thisis taken from the surrounding code. - With
new,thisis the new object.
const user = {
name: "Robin",
show() { console.log(this.name); }
};
user.show();
Output:
Robin
See The this keyword.
What is the difference between call, apply and bind?
function hello(greeting, mark) {
console.log(greeting + ", " + this.name + mark);
}
const person = { name: "Maria" };
hello.call(person, "Hi", "!");
hello.apply(person, ["Hello", "?"]);
const bound = hello.bind(person, "Hey");
bound(".");
Output:
Hi, Maria!
Hello, Maria?
Hey, Maria.
| Method | Runs now? | Arguments |
|---|---|---|
call | Yes | One by one |
apply | Yes | As an array |
bind | No, returns a new function | One by one, can be set in advance |
What is prototype and prototypal inheritance in JavaScript?
Every object has a hidden link to another object called its prototype. When you read a property that the object does not have, JavaScript looks for it in the prototype, then in the prototype of the prototype, and so on. This chain is prototypal inheritance.
function Person(name) {
this.name = name;
}
Person.prototype.greet = function () {
return "Hi, " + this.name;
};
const p = new Person("Robin");
console.log(p.greet());
console.log(Object.getPrototypeOf(p) === Person.prototype);
Output:
Hi, Robin
true
class and extends are a nicer syntax over the same prototype system. See Constructor Functions and Classes.
What is event bubbling and capturing in JavaScript?
When an event happens on an element, it travels in two phases.
- Capturing: from the top (
window) down to the target. - Bubbling: from the target back up to the top. This is the default for listeners.
parent.addEventListener("click", () => console.log("parent"));
child.addEventListener("click", () => console.log("child"));
// click on child
Output:
child
parent
To listen in the capturing phase pass true or { capture: true } as the third argument. Stop the travel with event.stopPropagation().
What is async and await in JavaScript?
async before a function makes it return a promise. await, used inside it, waits for a promise and gives its result, without blocking the rest of the program.
const wait = ms => new Promise(r => setTimeout(() => r("ready"), ms));
async function run() {
console.log("start");
const result = await wait(300);
console.log(result);
}
run();
console.log("after run()");
Output:
start
after run()
ready
Use try...catch for errors. See Async/Await and Fetch.
What is the difference between shallow copy and deep copy in JavaScript?
const original = { name: "Robin", skills: ["HTML"] };
const shallow = { ...original };
const deep = structuredClone(original);
original.skills.push("CSS");
console.log(shallow.skills);
console.log(deep.skills);
Output:
[ "HTML", "CSS" ]
[ "HTML" ]
The spread { ...original } copies only the top level, so skills is still the same array. structuredClone() copies everything. (JSON.parse(JSON.stringify(obj)) also works, but it loses functions and dates.)
What is the difference between debounce and throttle?
Both limit how often a function runs for events that fire very fast, like typing or scrolling.
| Technique | Runs | Good for |
|---|---|---|
| Debounce | Once, after the events stop for some time | Search box suggestions, resize |
| Throttle | At most once in every interval | Scroll and mouse move handlers |
function debounce(fn, delay) {
let timer;
return function (...args) {
clearTimeout(timer);
timer = setTimeout(() => fn.apply(this, args), delay);
};
}
input.addEventListener("input", debounce(search, 300));
The debounced function runs only 300 ms after the last key press. It uses a closure to remember the timer.
What is the difference between spread and rest operators?
// spread: expands
const a = [1, 2];
const b = [...a, 3];
console.log(b);
// rest: collects
function sum(...nums) {
return nums.reduce((t, n) => t + n, 0);
}
console.log(sum(1, 2, 3));
Output:
[ 1, 2, 3 ]
6
The same ... has different jobs: spread in a call or literal, rest in a function parameter list or destructuring. See ES6 Features.
What are Map and Set in JavaScript?
const map = new Map();
map.set("name", "Robin");
map.set(1, "one");
console.log(map.get("name"));
console.log(map.size);
const set = new Set([1, 2, 2, 3]);
console.log(set);
console.log(set.has(2));
Output:
Robin
2
Set(3) { 1, 2, 3 }
true
A Map is like an object, but keys can be of any type and it has a size. A Set keeps only unique values, so [...new Set(array)] removes duplicates.
What are modules in JavaScript?
// math.js
export const add = (a, b) => a + b;
export default function greet() { return "Hi"; }
// app.js
import greet, { add } from "./math.js";
console.log(add(2, 3), greet());
Output:
5 Hi
Use <script type="module"> in HTML. See JavaScript Modules.
What is a closure in JavaScript?
A closure is a function that keeps access to the variables of the place where it was created, even after that outer function has finished.
function makeCounter() {
let count = 0;
return function () {
count++;
return count;
};
}
const counter = makeCounter();
console.log(counter());
console.log(counter());
console.log(counter());
Output:
1
2
3
The variable count is private: only the inner function can change it. Closures are used for private data, counters, callbacks and function factories.
What is event delegation in JavaScript?
Instead of adding a listener to every child, you add one listener to the parent. Thanks to bubbling, the event of a child reaches the parent, and you find the real element with event.target.
const list = document.getElementById("list");
list.addEventListener("click", (event) => {
if (event.target.tagName === "LI") {
console.log("Clicked: " + event.target.textContent);
}
});
This saves memory and also works for items that are added later. See DOM EventListener.
What is a Promise in JavaScript?
A Promise represents a result that is not ready yet. It has three states: pending, fulfilled (success) and rejected (error).
const p = new Promise((resolve, reject) => {
setTimeout(() => resolve("Data loaded"), 500);
});
p.then(value => console.log(value))
.catch(err => console.log(err))
.finally(() => console.log("Finished"));
Output:
Data loaded
Finished
What is the event loop in JavaScript?
JavaScript runs one thing at a time, on the call stack. Timers and network requests are done by the browser in the background. When they finish, their callbacks wait in a queue, and the event loop moves them to the call stack when the stack is empty. Promise callbacks (microtasks) go before timer callbacks (macrotasks).
console.log("1");
setTimeout(() => console.log("2"), 0);
Promise.resolve().then(() => console.log("3"));
console.log("4");
Output:
1
4
3
2
The normal code runs first (1, 4), then the promise callback (3), then the timer callback (2), even with 0 milliseconds.