JavaScript & React
Secondary priority. These are supporting questions β answer confidently on the concept, then connect to backend experience where natural.
JavaScript Fundamentals
1. var vs let vs const
| var | let | const | |
|---|---|---|---|
| Scope | Function | Block | Block |
| Hoisting | Yes (undefined) | Yes (TDZ) | Yes (TDZ) |
| Reassign | Yes | Yes | No |
| Redeclare | Yes | No | No |
Always prefer const. Use let when reassignment is needed.
2. == vs ===
== β loose equality, performs type coercion (5 == "5" is true).
=== β strict equality, checks both value and type (5 === "5" is false).
Always use ===.
3. What is Hoisting?
JavaScript moves variable and function declarations to the top of their scope before execution.
varβ hoisted and initialized asundefinedlet/constβ hoisted but remain in the Temporal Dead Zone until the line of declaration
4. What is the Temporal Dead Zone (TDZ)?
The period between entering a scope and initializing a let or const variable. Accessing it before initialization throws ReferenceError.
5. What is a Closure?
A function that retains access to variables from its outer scope even after the outer function has finished executing.
function counter() {
let count = 0;
return () => ++count; // closure over 'count'
}
const inc = counter();
inc(); // 1
inc(); // 2Uses: data privacy, callbacks, memoization.
6. What is Lexical Scope?
Inner functions can access variables from their outer scope. Scope is determined by where functions are written, not where theyβre called.
7. Arrow functions vs Regular functions
| Arrow | Regular | |
|---|---|---|
this | Lexical (inherited) | Own this |
arguments | No | Yes |
| Constructor | No | Yes |
| Syntax | Shorter | Longer |
8. Destructuring
Extract values from arrays or objects.
const { name, age } = user;
const [first, ...rest] = arr;9. Spread and Rest
Spread (...) β expands array/object: const copy = [...arr]
Rest (...) β collects remaining values: function sum(...nums) {}
10. Template Literals
Allow embedded expressions using backticks.
`Hello ${name}`11. Default Parameters
Assign default values if arguments are omitted.
function greet(name = "Guest") { ... }12. Optional Chaining and Nullish Coalescing
user?.address?.city // safely access nested β returns undefined if any is null
name ?? "Guest" // returns right side only if left is null or undefinedAsync JavaScript
13. What is a Callback?
A function passed to another function and executed later. Can lead to βcallback hellβ β deeply nested code.
14. Callback Hell
Deeply nested callbacks that reduce readability. Solved using Promises or async/await.
15. What is a Promise?
Represents the eventual completion or failure of an async operation.
States: Pending β Fulfilled or Rejected
Methods: .then() Β· .catch() Β· .finally()
16. Promise Methods (Static)
Promise.all()β waits for all to fulfill, or fails if any fails.Promise.allSettled()β waits for all to finish, regardless of success.Promise.race()β resolves/rejects as soon as the first promise finishes.Promise.any()β resolves as soon as any promise fulfills.
17. async/await
Syntactic sugar over Promises. Makes async code look synchronous while remaining non-blocking.
async function fetchUser(id) {
const user = await db.query(id); // pauses here, doesn't block
return user;
}18. async vs Promise
async functions implicitly return a Promise. await is used to pause execution until a Promise resolves. They are functionally equivalent to .then() chains but more readable.
19. What is the Event Loop?
JavaScript is single-threaded. The Event Loop continuously checks:
- Call Stack β currently executing code
- Microtask Queue β Promise callbacks (higher priority)
- Callback Queue β setTimeout, DOM events
Microtasks run before the next callback queue item.
20. Call Stack
A LIFO (Last In, First Out) stack that stores currently executing function calls.
21. Microtask Queue
A higher-priority queue executed before the callback queue. Contains Promise callbacks and queueMicrotask().
22. Callback Queue (Macrotask Queue)
Stores asynchronous callbacks from setTimeout, DOM events, and I/O.
23. setTimeout(fn, 0) β when does it run?
Not immediately. The callback is placed in the Callback Queue and only runs after the current call stack is empty and all microtasks complete.
24. Array methods
| Method | Returns | Use |
|---|---|---|
map() | New array (same length) | Transform each element |
filter() | New array (shorter) | Keep matching elements |
reduce() | Single value | Aggregate |
forEach() | undefined | Side effects only |
find() | First match | Single element search |
25. find() vs filter()
find() returns the first matching element (or undefined).
filter() returns a new array of all matching elements (or an empty array).
26. Object.keys(), Object.values(), Object.entries()
Object.keys()β Returns an array of keys.Object.values()β Returns an array of values.Object.entries()β Returns an array of[key, value]pairs.
27. Deep Copy vs Shallow Copy
Shallow β Object.assign({}, obj) or {...obj}. Nested objects are still shared references.
Deep β JSON.parse(JSON.stringify(obj)) (simple), or structuredClone() (modern).
React
28. What is React?
JavaScript library for building reusable component-based user interfaces. Uses a declarative approach β describe what the UI should look like, React handles updates.
29. What is JSX?
A syntax extension allowing HTML-like code inside JavaScript. React compiles it down to React.createElement() calls.
30. What is a Component?
A reusable piece of UI that accepts inputs (props) and manages its own state.
31. Functional Component vs Class Component
Functional components use Hooks and are the modern standard.
Class components use lifecycle methods (componentDidMount, etc.) and are now less common.
32. Props vs State
Props β passed from parent, read-only inside the component.
State β managed within the component, can change over time and triggers re-renders.
33. useState()
Hook for managing component state.
const [count, setCount] = useState(0);34. useEffect()
Runs side effects after render: API calls, timers, subscriptions.
useEffect(() => {
fetchData();
return () => cleanup(); // cleanup on unmount
}, [dependency]); // runs when 'dependency' changesDependency array:
[]β runs once on mount[val]β runs whenvalchanges- Omitted β runs after every render
35. useMemo() vs useCallback()
useMemo() β memoizes a computed value. Avoids expensive recalculation.
useCallback() β memoizes a function reference. Avoids recreating functions on every render.
const expensiveValue = useMemo(() => compute(data), [data]);
const handleClick = useCallback(() => doSomething(id), [id]);36. useMemo vs useCallback
useMemo memoizes the result of a function call.
useCallback memoizes the function reference itself.
37. What is the Virtual DOM?
An in-memory representation of the real DOM. React compares the new Virtual DOM with the previous version (diffing/reconciliation) and applies only the minimal set of changes to the real DOM. Improves rendering performance.
38. Controlled vs Uncontrolled Components
Controlled β form element value managed by React state. Single source of truth.
Uncontrolled β form element manages its own state. Access via ref.
39. Context API
Shares state across components without prop drilling. Useful for themes, auth, language settings.
const ThemeContext = React.createContext('light');
// Provider wraps the tree, Consumer/useContext reads the value40. What is Prop Drilling?
Passing props through multiple intermediate components just to reach a deeply nested child. Solved with Context API or state management (Zustand, Redux).
41. React Keys
Unique identifiers used by React to track list items during reconciliation. Helps React know which items were added, removed, or reordered.
Use stable, unique IDs β not array indices.
42. React Fragment
Groups multiple elements without adding an extra node to the DOM (<React.Fragment> or <>...</>).
43. React component lifecycle (functional)
- Mount β
useEffect(() => {}, []) - Update β
useEffect(() => {}, [dep]) - Unmount β cleanup function returned from
useEffect
TypeScript
44. Why TypeScript?
Adds static typing to JavaScript. Catches type errors at compile time, improves IDE support and code maintainability.
45. Interface vs Type
Interface β best for object shapes. Can be extended and merged.
Type β more flexible. Supports unions, intersections, tuples, primitives.
interface User { name: string; age: number }
type ID = string | number;46. Generics
Write reusable, type-safe code without sacrificing flexibility.
function identity<T>(value: T): T { return value; }
identity<string>("hello");
identity<number>(42);47. Union Types
A variable that can hold one of several types.
type Result = string | number | null;48. Optional Properties and Optional Chaining
interface User { name: string; age?: number } // age is optional
const age = user?.age; // safe access49. any vs unknown
any β disables type checking. Avoid.
unknown β type-safe alternative. Must check type before using.
function parse(input: unknown) {
if (typeof input === "string") return input.toUpperCase();
}50. Type Narrowing
Refining a broad type to a specific one using checks: typeof, instanceof, or type guards.
51. Enums
Named set of constant values.
enum Status { Pending, Approved, Rejected }
const s: Status = Status.Approved;52. Strict Mode
TypeScript compiler option ("strict": true) that enables rigorous type checking β catches more errors at compile time.
53. Type Assertion
Tells TypeScript to treat a value as a specific type, overriding the compilerβs inference.
const input = document.getElementById("id") as HTMLInputElement;