JavaScript interviews are rarely about remembering syntax. Interviewers increasingly want to know whether you understand why JavaScript behaves the way it does—especially around scope, closures, asynchronous execution, prototypes, type coercion, and this.
The most useful way to prepare for javascript interview questions is therefore to understand the execution model rather than memorize isolated definitions. Recent interview-preparation resources consistently emphasize closures, the event loop, promises and async/await, prototypes, hoisting, this, equality, ES6+ syntax, array methods, and practical patterns such as debounce and throttle.
Quick answer: JavaScript interviews commonly test variables and scope, closures, hoisting, this, prototypes, type coercion, the event loop, Promises, async/await, ES modules, DOM events, array methods, and coding patterns such as debounce. Strong candidates can explain these concepts, predict code output, and apply them to practical programming problems.
JavaScript Interview Questions About the Fundamentals
1. What is JavaScript?
JavaScript is a high-level, dynamically typed programming language primarily associated with interactive web applications. It runs natively in web browsers and can also run outside browsers through environments such as Node.js.
JavaScript supports multiple programming styles, including procedural, functional, event-driven, and object-oriented programming.
Functions are first-class values, objects use prototype-based inheritance, and asynchronous operations can be coordinated through callbacks, Promises, and async/await.
2. What are the primitive data types in JavaScript?
JavaScript has seven primitive types:
stringnumberbigintbooleanundefinedsymbolnull
Everything else, including arrays and functions, is treated as an object or object-like value for many language operations.
One interview trap involves null:
typeof null; // "object"
That result is a historical JavaScript behavior. It does not mean null is actually an object.
3. What is the difference between var, let, and const?
This is one of the most frequently covered JavaScript fundamentals in current interview material.
| Feature | var | let | const |
|---|---|---|---|
| Scope | Function | Block | Block |
| Redeclaration | Yes | No in same scope | No in same scope |
| Reassignment | Yes | Yes | No |
| Hoisted | Yes | Yes | Yes |
| Accessible before declaration | undefined | ReferenceError | ReferenceError |
var declarations are initialized with undefined during environment setup.
let and const also participate in declaration instantiation, but accessing them before initialization results in a ReferenceError. This region is commonly called the Temporal Dead Zone (TDZ).
Prefer const when the binding will not be reassigned and let when reassignment is necessary.
4. Does const make an object immutable?
No.
const prevents reassignment of the variable binding. It does not automatically freeze the object referenced by that variable.
const user = {
name: "Sara"
};
user.name = "Ali"; // allowed
This is not allowed:
user = {}; // TypeError
If you need to prevent certain object mutations, Object.freeze() may help, although its standard behavior is shallow rather than recursively freezing every nested object.
5. What is the difference between undefined and null?
undefined normally indicates that a value has not been assigned.
null is typically used deliberately to represent the absence of a value.
let a;
console.log(a); // undefined
let user = null;
console.log(user); // null
They are distinct values:
null === undefined; // false
null == undefined; // true
The second expression demonstrates loose equality coercion.
6. What is the difference between == and ===?
== performs abstract equality comparison and may coerce operands before comparing them.
=== performs strict equality comparison without that type coercion.
5 == "5"; // true
5 === "5"; // false
In most application code, strict equality is easier to reason about because the operands are not implicitly converted before comparison.
Type coercion remains a common interview topic because JavaScript’s conversion rules can produce surprising results.
7. What is type coercion?
Type coercion occurs when JavaScript converts a value from one type to another.
It can be explicit:
Number("25"); // 25
String(100); // "100"
Or implicit:
"5" + 2; // "52"
5 * "2"; // 10
The + operator performs string concatenation when one relevant operand is a string, while numeric operators such as multiplication generally attempt numeric conversion.
Interviewers may ask you to predict these results to see whether you understand JavaScript’s conversion rules rather than simply its syntax.
8. What are truthy and falsy values?
Falsy values are values that become false in a Boolean context.
Common falsy values include:
false
0
-0
0n
""
null
undefined
NaN
Most other values are truthy, including:
[]
{}
"0"
"false"
For example:
if ([]) {
console.log("runs");
}
The message is printed because an empty array is truthy.
JavaScript Interview Questions About Scope, Hoisting, and Closures
Current interview guides repeatedly identify scope, closures, and hoisting as core areas candidates should understand deeply.
9. What is scope in JavaScript?
Scope determines where variables and functions can be accessed.
The main forms are:
Global scope: available broadly within the relevant global environment.
Function scope: variables declared with var inside a function belong to that function.
Block scope: let and const declarations are scoped to blocks such as loops and if statements.
{
let x = 10;
const y = 20;
}
console.log(x); // ReferenceError
Understanding scope is essential because closures, variable shadowing, and many asynchronous bugs depend on it.
10. What is lexical scope?
Lexical scope means variable accessibility is determined by where functions and blocks are written in the source code.
const message = "Hello";
function outer() {
function inner() {
console.log(message);
}
inner();
}
outer();
inner() can access message by following its surrounding lexical environments.
A function’s lexical environment is based on where the function was defined, not simply where it happens to be called.
11. What is hoisting in JavaScript?
Hoisting is the commonly used term for behavior caused by declarations being processed before normal execution reaches their source-code position.
Consider:
console.log(x);
var x = 10;
The result is:
undefined
A useful conceptual model is:
var x;
console.log(x);
x = 10;
However, saying that JavaScript literally “moves declarations to the top” is only a teaching shortcut. The behavior comes from how bindings are created and initialized before statement execution. Modern interview material increasingly emphasizes explaining this mechanism rather than repeating the shortcut.
12. What is the Temporal Dead Zone?
The Temporal Dead Zone is the period between entering a scope and initializing a let, const, or class declaration.
console.log(score);
let score = 10;
This throws a ReferenceError.
The binding exists, but it cannot be accessed before its declaration is initialized.
13. What is a closure?
A closure occurs when a function retains access to variables from its lexical environment even after the outer function has finished executing.
function createCounter() {
let count = 0;
return function () {
count++;
return count;
};
}
const counter = createCounter();
console.log(counter()); // 1
console.log(counter()); // 2
The returned function still has access to count.
Closures are widely used for encapsulating state, callbacks, function factories, memoization, currying, and module-like patterns.
14. Why does the classic var loop behave unexpectedly with setTimeout?
Consider:
for (var i = 0; i < 3; i++) {
setTimeout(() => console.log(i), 0);
}
It eventually prints:
3
3
3
var creates one function-scoped binding. By the time the callbacks execute, the loop has finished and that binding contains 3.
Using let creates a new per-iteration binding:
for (let i = 0; i < 3; i++) {
setTimeout(() => console.log(i), 0);
}
Output:
0
1
2
This question tests closures, scope, asynchronous execution, and the difference between var and let simultaneously.
15. What is variable shadowing?
Variable shadowing happens when a declaration in an inner scope uses the same name as one in an outer scope.
const name = "Global";
function showName() {
const name = "Local";
console.log(name);
}
showName(); // Local
Inside showName, the local variable shadows the outer variable.
JavaScript Interview Questions About Functions and this
16. What are first-class functions?
JavaScript treats functions as first-class values.
That means functions can:
- Be assigned to variables
- Be stored in objects or arrays
- Be passed to other functions
- Be returned from functions
function greet(name) {
return `Hello ${name}`;
}
function execute(fn, value) {
return fn(value);
}
execute(greet, "Ava");
This capability is fundamental to callbacks, functional programming, event handlers, and higher-order functions.
17. What is a higher-order function?
A higher-order function either accepts another function as an argument, returns a function, or both.
Examples include:
map()
filter()
reduce()
A simple custom example is:
function multiplyBy(value) {
return function (number) {
return number * value;
};
}
const double = multiplyBy(2);
console.log(double(5)); // 10
Higher-order functions are closely connected to closures and functional programming.
18. What is the difference between regular and arrow functions?
Arrow functions provide shorter syntax:
const add = (a, b) => a + b;
But the difference is not merely cosmetic.
Arrow functions do not create their own this binding. They capture this lexically from the surrounding context.
They also do not have their own arguments object and cannot normally be used as constructors with new.
Regular functions are often more appropriate for object methods when dynamic this behavior is required.
19. How does this work in JavaScript?
The value of this for a regular function depends largely on how the function is called.
const user = {
name: "John",
show() {
console.log(this.name);
}
};
user.show(); // John
Here this refers to user because the method is called through user.
The important interview principle is:
For regular functions, examine the call site rather than only the place where the function was defined.
Arrow functions behave differently because they inherit this lexically.
20. What are call(), apply(), and bind()?
These methods allow you to control this for ordinary functions.
function introduce(city) {
console.log(`${this.name} from ${city}`);
}
const person = {
name: "Alex"
};
introduce.call(person, "London");
call() invokes the function immediately with arguments listed separately.
introduce.apply(person, ["London"]);
apply() also invokes immediately but receives arguments as an array or array-like collection.
const boundIntroduce = introduce.bind(person);
boundIntroduce("London");
bind() returns a new function with the specified this value.
21. What is a callback function?
A callback is a function passed to another function so that it can be invoked later.
function processUser(name, callback) {
callback(name);
}
processUser("Mia", name => {
console.log(`Hello ${name}`);
});
Callbacks are common in event handling and asynchronous APIs, although Promise-based APIs often make complex asynchronous flows easier to compose.
22. What is currying?
Currying transforms a function taking several arguments into a sequence of functions that each accept an argument.
Instead of:
add(2, 3);
A curried version might be:
add(2)(3);
Example:
const add = a => b => a + b;
console.log(add(2)(3)); // 5
Currying can help build reusable specialized functions and appears frequently in functional programming discussions.
JavaScript Interview Questions About Objects and Prototypes
23. What is prototypal inheritance?
JavaScript objects can inherit properties and methods through a prototype chain.
If a property does not exist directly on an object, JavaScript can search the object’s prototype, then that prototype’s prototype, continuing until the property is found or the chain ends.
const animal = {
speak() {
console.log("sound");
}
};
const dog = Object.create(animal);
dog.speak();
dog does not have its own speak method, but JavaScript finds it through the prototype chain.
Prototypes and inheritance remain recurring JavaScript interview subjects.
24. What is the prototype chain?
Every ordinary object can have an internal prototype reference.
When accessing:
object.property
JavaScript first checks the object itself.
If the property is missing, it searches the object’s prototype and continues upward.
Conceptually:
object
↓
prototype
↓
prototype's prototype
↓
...
↓
null
This lookup sequence is the prototype chain.
25. Are JavaScript classes different from prototypes?
The class syntax provides a cleaner way to express constructor and inheritance patterns, but JavaScript’s object model remains prototype-based.
class Person {
constructor(name) {
this.name = name;
}
greet() {
return `Hello ${this.name}`;
}
}
Methods such as greet are associated with Person.prototype.
Classes therefore do not replace the prototype system; they provide structured syntax over it.
26. What is the difference between shallow and deep copying?
A shallow copy duplicates only the top-level structure. Nested objects remain shared references.
const original = {
profile: {
name: "Sam"
}
};
const copy = { ...original };
copy.profile.name = "Alex";
console.log(original.profile.name); // Alex
A deep copy recursively duplicates nested structures so they do not share the same mutable nested objects.
For supported values, modern environments provide:
const deepCopy = structuredClone(original);
structuredClone() supports many built-in data types but is not a universal clone mechanism for every possible JavaScript value.
27. What is destructuring?
Destructuring extracts values from arrays or properties from objects.
Object example:
const user = {
name: "Emma",
age: 25
};
const { name, age } = user;
Array example:
const numbers = [10, 20];
const [first, second] = numbers;
It is especially useful for function parameters, configuration objects, and module imports.
28. What is the difference between spread and rest syntax?
Both use ..., but their purpose depends on context.
Spread expands values:
const a = [1, 2];
const b = [...a, 3];
Rest collects remaining values:
function sum(...numbers) {
return numbers.reduce((total, n) => total + n, 0);
}
A concise interview explanation is:
Spread expands; rest collects.
Asynchronous JavaScript Interview Questions
The event loop, microtasks, Promises, and async/await consistently appear among the most emphasized subjects in current JavaScript interview guides.
29. Is JavaScript single-threaded?
JavaScript code in a typical execution context runs on a single main execution thread, meaning one piece of JavaScript executes on that thread at a time.
That does not mean the overall runtime can perform only one operation.
Browser APIs and runtime facilities can handle timers, networking, user events, and other operations outside the JavaScript call stack. Completed asynchronous work is coordinated back into JavaScript through task queues and the event loop.
30. What is the JavaScript event loop?
The event loop coordinates execution between the JavaScript call stack and queued asynchronous work.
At a simplified level:
- Synchronous JavaScript runs on the call stack.
- Runtime facilities handle asynchronous operations.
- Relevant callbacks become eligible to run through queues.
- Microtasks are processed at defined checkpoints.
- The runtime continues with subsequent tasks.
Understanding the event loop explains why JavaScript can remain responsive while dealing with timers, network operations, events, and Promise callbacks.
31. What is the difference between microtasks and tasks?
Promise reactions and queueMicrotask() schedule microtasks.
Timers such as setTimeout() schedule tasks in browser environments.
Consider:
console.log("A");
setTimeout(() => {
console.log("B");
}, 0);
Promise.resolve().then(() => {
console.log("C");
});
console.log("D");
Output:
A
D
C
B
The synchronous statements run first. The Promise reaction runs as a microtask before the timer callback becomes the next relevant task.
Predicting examples like this is a common way to test whether candidates genuinely understand the event loop.
32. Why doesn’t setTimeout(fn, 0) execute immediately?
A delay of zero does not mean “execute now.”
It means the timer can become eligible after the minimum scheduling requirements have been satisfied. Its callback still cannot interrupt JavaScript that is already running.
console.log(1);
setTimeout(() => console.log(2), 0);
console.log(3);
Output:
1
3
2
33. What is a Promise?
A Promise represents the eventual outcome of an asynchronous operation.
A Promise can be:
- Pending
- Fulfilled
- Rejected
Example:
const promise = new Promise((resolve, reject) => {
const success = true;
if (success) {
resolve("Completed");
} else {
reject(new Error("Failed"));
}
});
You can consume it using:
promise
.then(value => console.log(value))
.catch(error => console.error(error))
.finally(() => console.log("Finished"));
Promises make asynchronous workflows easier to compose than deeply nested callback structures.
34. What is async/await?
async and await provide syntax for working with Promises in a style that often resembles synchronous control flow.
async function getUser() {
const response = await fetch("/api/user");
const data = await response.json();
return data;
}
An async function returns a Promise.
await pauses progress within that async function until the awaited value settles, without blocking the entire JavaScript runtime thread while asynchronous work is pending.
35. How do you handle errors with async/await?
A common pattern uses try...catch:
async function loadData() {
try {
const response = await fetch("/api/data");
if (!response.ok) {
throw new Error(`HTTP error: ${response.status}`);
}
return await response.json();
} catch (error) {
console.error(error);
throw error;
}
}
One practical detail matters: fetch() does not reject merely because a server responds with an HTTP error status such as 404 or 500. Checking response.ok is therefore often necessary.
36. What is Promise.all()?
Promise.all() accepts an iterable of values or Promises and returns a Promise that fulfills when all inputs fulfill.
const [user, posts] = await Promise.all([
fetchUser(),
fetchPosts()
]);
Independent asynchronous operations can start together rather than being awaited one after another.
If an input Promise rejects, the returned Promise.all() Promise rejects with that reason.
37. What is the difference between Promise.all(), allSettled(), race(), and any()?
| Method | Main behavior |
|---|---|
Promise.all() | Fulfills when all fulfill; rejects when an input rejects |
Promise.allSettled() | Waits until every input settles |
Promise.race() | Settles with the first input to settle |
Promise.any() | Fulfills with the first input to fulfill |
Use the method that matches the desired failure and completion semantics.
For example, allSettled() is useful when you want results from every independent operation even if some fail.
Array and Modern JavaScript Interview Questions
38. What is the difference between map(), filter(), and reduce()?
These methods solve different problems.
map() transforms each element:
const doubled = [1, 2, 3].map(n => n * 2);
// [2, 4, 6]
filter() keeps elements satisfying a condition:
const even = [1, 2, 3, 4].filter(n => n % 2 === 0);
// [2, 4]
reduce() combines array elements into an accumulated result:
const total = [1, 2, 3].reduce(
(sum, n) => sum + n,
0
);
// 6
Current interview resources continue to group these higher-order array methods among core JavaScript preparation topics.
39. What is the difference between map() and forEach()?
map() returns a new array containing the callback’s returned values.
const result = [1, 2, 3].map(n => n * 2);
forEach() is primarily used to execute a callback for each element and returns undefined.
[1, 2, 3].forEach(n => {
console.log(n);
});
Use map() when you want to transform an array into another array. Use forEach() when the purpose is a side effect rather than producing a transformed collection.
40. What are optional chaining and nullish coalescing?
Optional chaining (?.) safely stops a property-access chain when the preceding value is null or undefined.
const city = user?.address?.city;
Nullish coalescing (??) provides a fallback only for null or undefined.
const username = input ?? "Guest";
It differs from ||:
0 || 10; // 10
0 ?? 10; // 0
This matters when 0, false, or an empty string is a valid value.
Optional chaining and nullish coalescing are among the modern language features appearing in current interview preparation material.
41. What are JavaScript modules?
JavaScript modules allow code to be split into reusable files with explicit imports and exports.
// math.js
export function add(a, b) {
return a + b;
}
Then:
import { add } from "./math.js";
ECMAScript modules use import and export syntax and provide their own module scope.
Modules improve code organization, dependency management, reuse, and maintainability.
42. What are template literals?
Template literals use backticks and support interpolation:
const name = "David";
const message = `Hello, ${name}`;
They also support multiline strings:
const text = `First line
Second line`;
They are usually clearer than manual string concatenation when dynamic values are embedded in text.
DOM and Browser JavaScript Interview Questions
43. What is event bubbling?
When an event occurs on an element, it can propagate upward through ancestor elements during the bubbling phase.
Suppose a button sits inside a div.
Clicking the button can trigger relevant listeners on the button and then on its ancestors as propagation continues.
This behavior enables event delegation.
44. What is event delegation?
Event delegation attaches a listener to a parent rather than separately attaching listeners to many children.
document
.querySelector("#list")
.addEventListener("click", event => {
if (event.target.matches("button")) {
console.log("Button clicked");
}
});
It works because events such as click normally bubble.
Benefits include fewer listeners and easier handling of matching child elements that are added dynamically.
DOM event delegation remains a recurring practical interview topic.
45. What is the difference between preventDefault() and stopPropagation()?
preventDefault() prevents the browser’s default action for an event when that event is cancelable.
Example:
event.preventDefault();
This might stop a link from navigating.
stopPropagation() stops the event from continuing through the propagation path:
event.stopPropagation();
They solve different problems and should not be treated as interchangeable.
Advanced JavaScript Interview Questions and Coding Patterns
46. What is debouncing?
Debouncing delays execution until a specified period has passed without another call.
A common implementation is:
function debounce(fn, delay) {
let timer;
return function (...args) {
clearTimeout(timer);
timer = setTimeout(() => {
fn.apply(this, args);
}, delay);
};
}
For a search input, debouncing can avoid triggering expensive work for every keystroke. Instead, the function runs after the user pauses typing.
Debounce implementation and the distinction between debounce and throttle appear frequently in current JavaScript interview resources.
47. What is throttling?
Throttling limits how frequently a function can execute.
A basic implementation might look like:
function throttle(fn, delay) {
let waiting = false;
return function (...args) {
if (waiting) return;
fn.apply(this, args);
waiting = true;
setTimeout(() => {
waiting = false;
}, delay);
};
}
The practical difference is:
Debounce: wait until calls stop.
Throttle: allow execution at a limited frequency while calls continue.
For example, debouncing often suits search inputs, while throttling can suit frequently firing events where periodic updates are sufficient.
48. What is memoization?
Memoization caches results so repeated calls with the same relevant input can reuse previous computation.
function memoize(fn) {
const cache = new Map();
return function (value) {
if (cache.has(value)) {
return cache.get(value);
}
const result = fn(value);
cache.set(value, result);
return result;
};
}
Memoization is most useful when a computation is expensive and its result can safely be reused for the same input.
A production implementation must also consider cache-key construction, memory growth, object arguments, invalidation, and whether the underlying function is actually pure enough to cache.
49. What is garbage collection in JavaScript?
JavaScript engines automatically manage memory.
Conceptually, the garbage collector identifies memory that is no longer reachable from active roots and can eventually reclaim it.
Developers normally do not free memory manually.
However, memory leaks can still occur when references remain reachable unnecessarily.
Common sources include:
- Forgotten event listeners
- Long-lived timers
- Growing caches
- References retained by closures
- Detached DOM structures still referenced by JavaScript
The practical lesson is that automatic garbage collection reduces manual memory management; it does not make memory leaks impossible.
50. What is the difference between synchronous and asynchronous JavaScript?
Synchronous code executes sequentially:
console.log("A");
console.log("B");
console.log("C");
Output:
A
B
C
Asynchronous APIs allow work to complete later without requiring the main JavaScript execution flow to sit idle waiting for it.
console.log("A");
setTimeout(() => {
console.log("B");
}, 0);
console.log("C");
Output:
A
C
B
This distinction connects directly to the call stack, event loop, Promises, timers, browser APIs, and async/await.
JavaScript Output-Based Interview Questions You Should Practice
Knowing definitions is useful, but many interviews use small code snippets to test whether you can apply the rules. Output-based JavaScript questions remain common in current interview preparation material.
What does this closure code print?
function outer() {
let count = 0;
return () => ++count;
}
const a = outer();
const b = outer();
console.log(a());
console.log(a());
console.log(b());
Output:
1
2
1
Each call to outer() creates a separate lexical environment, so a and b maintain independent count variables.
What does this Promise example print?
console.log("start");
Promise.resolve().then(() => {
console.log("promise");
});
setTimeout(() => {
console.log("timer");
}, 0);
console.log("end");
Output:
start
end
promise
timer
Synchronous code finishes first. The Promise reaction runs as a microtask before the timer callback runs as a later task.
What does this object-reference example print?
const first = {
score: 10
};
const second = first;
second.score = 20;
console.log(first.score);
Output:
20
Both variables reference the same object.
Reassigning a property through second therefore changes the object observed through first.
What happens here?
console.log(value);
let value = 5;
A ReferenceError occurs because value is accessed while its let binding is still in the Temporal Dead Zone.
Compare it with:
console.log(value);
var value = 5;
This prints:
undefined
Understanding why these snippets differ is more valuable than memorizing their output.
How to Answer javascript interview questions Effectively
Strong interview answers usually have three parts: define the concept, explain the mechanism, and give a small practical example.
For a closure question, for instance, do not stop at:
“A closure is an inner function.”
That definition is incomplete.
A stronger answer explains that a function retains access to its surrounding lexical environment and then demonstrates why that matters with private state, a callback, or a counter.
The same principle applies to the event loop. Instead of saying that JavaScript “handles asynchronous code,” explain the relationship among synchronous execution, the call stack, queued tasks, microtasks, and the runtime.
Recent interview guidance similarly emphasizes explaining the reasoning behind output rather than merely guessing what a snippet prints.
Practice explaining code aloud
Consider:
console.log("one");
setTimeout(() => console.log("two"), 0);
Promise.resolve().then(() => console.log("three"));
console.log("four");
Do not merely memorize:
one
four
three
two
Explain it:
oneis logged synchronously.- The timer callback is scheduled for later.
- The Promise reaction becomes a microtask.
fouris logged synchronously.- After the current synchronous work finishes, the microtask runs.
- The timer callback runs afterward as a task.
That reasoning transfers to unfamiliar interview questions.
What JavaScript Topics Should You Prioritize?
If preparation time is limited, focus first on the concepts that recur across current interview resources: scope and closures, var/let/const, hoisting and the TDZ, this, prototypes, type coercion, the event loop, Promises, async/await, array methods, and debounce/throttle.
Then move to modern JavaScript features such as destructuring, spread/rest syntax, optional chaining, nullish coalescing, modules, class private fields, and other ECMAScript additions relevant to the role. Current 2026 interview guides increasingly include these modern features alongside the traditional fundamentals.
For frontend positions, add DOM events, event delegation, browser APIs, performance, and practical UI patterns.
For Node.js or full-stack roles, go deeper into asynchronous execution, modules, error handling, networking, streams, runtime behavior, and server-side architecture appropriate to the position.
For senior roles, expect follow-up questions. An interviewer may start with “What is a closure?” and then move into memory retention, stale state, memoization, callback behavior, or real production scenarios. Likewise, an event-loop question can quickly become a discussion of microtasks, scheduling, responsiveness, and performance.
Final Preparation Checklist
Before an interview, make sure you can explain—not merely recognize—the following:
var,let, andconst- Primitive and reference-like value behavior
==versus===- Type coercion
- Truthy and falsy values
- Scope and lexical environments
- Hoisting and the Temporal Dead Zone
- Closures
- Regular versus arrow functions
this,call(),apply(), andbind()- Higher-order functions
- Prototypes and the prototype chain
- Classes
- Destructuring and spread/rest syntax
- Shallow versus deep copying
- The call stack and event loop
- Microtasks versus tasks
- Promises
async/await- Promise combinators
map(),filter(), andreduce()- ES modules
- Optional chaining and nullish coalescing
- Event bubbling and event delegation
- Debounce and throttle
- Memoization
- Basic memory-management concepts
The best way to prepare for javascript interview questions is to write small examples and explain their behavior without running them first. Predict the output, state the rule responsible for it, and then test your reasoning.
That approach turns interview preparation from memorizing dozens of answers into understanding a smaller set of JavaScript mechanisms that explain hundreds of possible questions.