189 questions with detailed answers
Q1. Explain the concept of hoisting in JavaScript
Answer: Hoisting means declarations are processed before code runs in a scope. var is hoisted and initialized as undefined; let/const/class are hoisted but stay in the temporal dead zone until their line runs (ReferenceError if accessed early). Function declarations hoist fully (name and body); function expressions only hoist the variable binding.
Q2. What are the differences between let, var, and const?
Answer: var is function-scoped, can be redeclared, and reads as undefined before its line. let and const are block-scoped and cannot be redeclared in the same scope; accessing them before declaration throws. const must be initialized and cannot be reassigned (object contents can still mutate). Prefer const by default, let when reassignment is needed.
Q3. What is the difference between == and === in JavaScript?
Answer: == is abstract equality and may coerce types before comparing. === is strict equality: different types are never equal. Prefer === in application code; a common exception is x == null, which matches both null and undefined.
Q4. What is the event loop in JavaScript runtimes?
Answer: The event loop schedules async work while JS stays single-threaded on the call stack. Completed async work queues callbacks as microtasks (Promises, queueMicrotask, MutationObserver) or macrotasks (setTimeout, I/O, UI events). When the stack is empty, all microtasks run before the next macrotask, which is why Promise callbacks usually beat setTimeout(0).
Q5. Explain event delegation in JavaScript
Answer: Event delegation attaches one listener on a parent and handles child events via bubbling (event.target). Benefits: fewer listeners, less memory, and automatic support for dynamically added children. Identify the real target carefully; non-bubbling events (focus, blur, mouseenter, mouseleave, scroll) need capture or other patterns.
Q6. Explain how this works in JavaScript
Answer: this is set by how a function is called: new / class constructors get the new instance; call/apply/bind set this explicitly; obj.method() uses obj; a bare call uses the global object (or undefined in strict mode). Arrow functions do not bind their own this — they capture this from the enclosing lexical scope.
Q7. Describe the difference between a cookie, sessionStorage and localStorage
Answer: Cookies are small (~4KB), optionally sent on every HTTP request, and can be HttpOnly. localStorage persists across sessions for an origin (~5MB) and is JS-only. sessionStorage is similar capacity but scoped to a tab and cleared when that tab closes. Prefer cookies for auth the server must see; Web Storage for client-only state.
Q8. Describe the difference between script, script async, and script defer
Answer: A classic script blocks HTML parsing while it downloads and runs. async downloads in parallel and runs as soon as ready (order not guaranteed). defer downloads in parallel and runs after HTML is parsed, in document order. type=module also defers and resolves imports first. Prefer defer/modules for page scripts that need the DOM.
Q9. What's the difference between null, undefined, and undeclared?
Answer: undefined means a declared binding has no assigned value (or a missing return/arg). null is an intentional empty value set by the developer. Undeclared means no binding exists at all — reading it throws ReferenceError. typeof null is the historic quirk 'object'; typeof undeclared is 'undefined' without throwing.
Q10. What's the difference between .call and .apply in JavaScript?
Answer: Both invoke a function with a chosen this. call takes arguments individually: fn.call(thisArg, a, b). apply takes them as an array-like: fn.apply(thisArg, [a, b]). Modern code often prefers spread: fn.call(thisArg, ...args).
Q11. Explain Function.prototype.bind in JavaScript
Answer: bind returns a new function with this permanently set to thisArg, and optionally prepends fixed arguments (partial application). Useful for callbacks and event handlers so methods keep the right receiver. Unlike call/apply, bind does not invoke immediately.
Q12. What advantage is there for using arrow syntax for a method in a constructor?
Answer: An arrow method created in a constructor lexically captures that instance as this, so call/apply/bind and extracting the method as a bare callback cannot rebind it. Trade-off: each instance gets its own function (not shared on the prototype), so use it when stable this matters more than memory.
Q13. Explain how prototypal inheritance works in JavaScript
Answer: Every object has an internal [[Prototype]]. Property lookup walks the object, then its prototype, and so on until found or null. Constructors put shared methods on Constructor.prototype; class extends does the same under the hood. Prefer Object.create / class extends / Object.setPrototypeOf carefully — it is delegation, not classical copy inheritance.
Q14. Difference between function Person(){}, const person = Person(), and const person = new Person()
Answer: function Person(){} declares a callable that can also be a constructor. Person() is a normal call — this is global/undefined and usually no useful instance is returned. new Person() creates an object, links its prototype, binds this to it, and returns that instance (unless the constructor returns another object).
Q15. Explain function foo() {} vs var foo = function() {} in JavaScript
Answer: function foo(){} is a declaration: the whole function is hoisted and callable earlier in the scope. var foo = function(){} is an expression: only the var binding is hoisted (undefined until assignment), so early calls throw TypeError. Named function expressions expose the name only inside the function.
Q16. What's a typical use case for anonymous functions in JavaScript?
Answer: Anonymous functions (or arrow callbacks) are passed to higher-order APIs: map/filter, setTimeout, event listeners, and Promise handlers. They also appear as IIFEs to create a private scope. Prefer named functions when stack traces and reuse matter.
Q17. What are the various ways to create objects in JavaScript?
Answer: Common options: object literals {}; new Object(); Object.create(proto); constructor functions with new; ES classes; and factories that return plain objects. Literals are default for one-offs; classes/constructors when you need many instances with shared methods.
Q18. What is a closure in JavaScript, and how/why would you use one?
Answer: A closure is a function that keeps access to variables from its lexical outer scope after that outer function has returned. Used for private state (module/counter patterns), callbacks, event handlers, and partial configuration. Avoid retaining large unused data through long-lived closures.
Q19. What is the definition of a higher-order function in JavaScript?
Answer: A higher-order function takes functions as arguments and/or returns a function. Examples: Array map/filter/reduce, setTimeout, and bind. They abstract repeated control flow so callers supply only the varying behavior.
Q20. What are the differences between ES2015 classes and ES5 function constructors?
Answer: class is mainly nicer syntax over prototypes: constructor method, methods on the prototype, static, extends, and super. ES5 needs manual .call(this), Object.create for the prototype chain, and fixing .constructor. Classes are not hoisted like function declarations and must be new'd.
Q21. Describe event bubbling in JavaScript and browsers
Answer: After the target phase, most events bubble from the target up through ancestors to the document/window. Bubbling enables event delegation. Unwanted parent handlers can be stopped with stopPropagation (use carefully).
Q22. Describe event capturing in JavaScript and browsers
Answer: Capturing runs from the root down toward the target before the target and bubble phases. Enable it with addEventListener(type, handler, true) or { capture: true }. Useful to intercept events early; bubbling is far more common day to day.
Q23. What is the difference between mouseenter and mouseover?
Answer: mouseenter does not bubble and fires when the pointer enters the element itself (not again for every child). mouseover bubbles and also fires when entering descendants, which can cause noisy parent callbacks. Prefer mouseenter/mouseleave for hover UI; mouseover when delegation via bubbling is needed.
Q24. What is 'use strict' in JavaScript for?
Answer: Strict mode opts into a safer JS dialect: accidental globals throw, silent failures become errors, duplicate params are illegal, and bare this is undefined. Modules and many class bodies are strict by default. Prefer writing modern module code so you get strict mode automatically.
Q25. Explain the difference between synchronous and asynchronous functions in JavaScript
Answer: Synchronous code runs to completion on the call stack before anything else; long work blocks the UI. Asynchronous APIs start work and continue later via callbacks, Promises, or async/await so the runtime can handle other tasks meanwhile. Use async for I/O and timers; keep CPU-heavy work short or move it to workers.
Q26. What are the pros and cons of using Promises instead of callbacks?
Answer: Promises flatten async flow, chain with then/catch, compose with Promise.all/race/allSettled, and integrate with async/await — avoiding deep callback nesting. Costs: slightly more concepts, and forgotten rejections become unhandled rejection warnings. Prefer Promises/async for new code.
Q27. Explain AJAX in as much detail as possible
Answer: AJAX means updating a page by fetching data asynchronously without a full reload. Historically XMLHttpRequest; today usually fetch() (or Axios). You send HTTP requests, parse JSON/HTML/text, then patch the DOM or app state. It is a pattern, not a single API.
Q28. What are the advantages and disadvantages of using AJAX?
Answer: Pros: snappier UX, less bandwidth than full reloads, keeps client state. Cons: needs JS, harder deep-linking/bookmarking unless you manage history, SEO needs SSR/SSG for public content, and you must handle loading/error states carefully.
Q29. What are the differences between XMLHttpRequest and fetch()?
Answer: fetch is promise-based and has a cleaner API; XHR uses events. fetch does not reject on HTTP 4xx/5xx (check response.ok). Cancellation uses AbortController with fetch vs xhr.abort(). XHR has richer upload progress historically; fetch is standard across modern runtimes and preferred for new code.
Q30. How do you abort a web request using AbortController?
Answer: Create const controller = new AbortController(), pass { signal: controller.signal } to fetch, then call controller.abort() when the user cancels or navigates away. Catch AbortError separately from real failures. Also useful to ignore stale responses when a newer request supersedes an older one.
Q31. What are JavaScript polyfills for?
Answer: A polyfill implements a modern language feature or Web API in older environments (e.g. Array.prototype.includes, Promise). Ship them via libraries like core-js or selective imports, ideally behind feature detection. Prefer official/spec-aligned polyfills over ad-hoc prototype hacks.
Q32. Why is extending built-in JavaScript objects not a good idea?
Answer: Patching Array.prototype or similar risks collisions when two libraries add the same method differently, and can break for-in assumptions. The rare acceptable case is a carefully gated polyfill for a standardized method that is missing.
Q33. Why leave the global JavaScript scope alone?
Answer: Globals invite name clashes, harder testing, accidental coupling, and security exposure to other scripts. Prefer modules, block scope, and passing dependencies explicitly. Browser code shares one window — keep it minimal.
Q34. Explain the differences between CommonJS and ES modules
Answer: CommonJS uses require/module.exports and loads synchronously (classic Node). ESM uses import/export, is statically analyzable (tree-shaking), and loads asynchronously in browsers. Node supports both; new browser and isomorphic code should prefer ESM.
Q35. What are the various data types in JavaScript?
Answer: Primitives: number, string, boolean, undefined, null, symbol, bigint. Everything else is an object (including arrays, functions, dates, maps, sets, regexes). Primitives are copied by value; objects are referenced.
Q36. What language constructs do you use for iterating over object properties and array items?
Answer: Objects: Object.keys/values/entries, or for...in with Object.hasOwn checks. Arrays: for, for...of, forEach, and transforming helpers map/filter/reduce. Prefer for...of for values; avoid for...in on arrays.
Q37. What are the benefits of spread syntax and how does it differ from rest?
Answer: Spread expands iterables/objects into elements or properties: [...arr], { ...obj }. Rest collects leftovers into an array/object: function f(...args) or const { a, ...rest } = obj. Same ... token, opposite direction.
Q38. What are iterators and generators and what are they used for?
Answer: An iterator exposes next() returning { value, done }. Generators (function*) pause at yield and return an iterator, enabling lazy/infinite sequences and custom iteration. for...of and spread consume iterables that provide [Symbol.iterator].
Q39. Explain the difference between mutable and immutable objects
Answer: Mutable objects can change in place (default for plain objects/arrays). Immutable values are replaced wholesale when updated — safer for reasoning and React-style state. Object.freeze makes shallow immutability; deep immutability needs structuredClone patterns or libraries.
Q40. What is the difference between a Map and a plain object?
Answer: Map keys can be any value (including objects), insertion order is guaranteed, size is O(1), and iteration is built-in. Plain objects coerce keys to string/symbol, inherit Object.prototype, and are JSON-serializable by default. Use Map for frequent add/delete keyed collections; objects for records/JSON shapes.
Q41. What are the differences between Map/Set and WeakMap/WeakSet?
Answer: WeakMap/WeakSet only accept objects as keys/values and hold them weakly so GC can collect them when nothing else references them — ideal for metadata caches without leaks. They are not iterable and have no size. Map/Set hold strong references and support full iteration.
Q42. Why might you want to create static class members?
Answer: static properties/methods hang on the constructor, not instances — good for constants, factories, and utilities namespaced to the class (Math.max style). Avoid overusing statics for hidden global state.
Q43. What are Symbols used for in JavaScript?
Answer: Symbol is a unique primitive often used as an object key to avoid collisions and to hide details from casual enumeration (Object.keys skips symbol keys). Well-known symbols customize language behavior (e.g. Symbol.iterator). Each Symbol() call creates a distinct value.
Q44. What are server-sent events?
Answer: SSE (EventSource) is a one-way HTTP stream of text events from server to browser with automatic reconnect. Simpler than WebSockets when only the server pushes updates (feeds, notifications). WebSockets are bidirectional and support binary frames.
Q45. What are JavaScript object property flags and descriptors?
Answer: Each property has writable, enumerable, and configurable flags, plus value or get/set. Read with Object.getOwnPropertyDescriptor; define with Object.defineProperty. Used to lock APIs, hide fields from enumeration, or implement accessors.
Q46. What are JavaScript object getters and setters for?
Answer: get/set accessors run logic on read/write — validation, derived values, or encapsulation — while still looking like normal properties. Useful for computed fields and protecting invariants.
Q47. What are proxies in JavaScript used for?
Answer: Proxy intercepts fundamental operations (get, set, apply, etc.) via a handler. Used for validation, logging, reactive systems, virtual properties, and test doubles. Powerful but add complexity and can surprise performance-sensitive code.
Q48. What tools and techniques do you use for debugging JavaScript code?
Answer: Browser DevTools breakpoints, debugger, and console.*; network panels; React/Vue/Redux DevTools for UI state; source maps for transpiled code. Reproduce with minimal cases, read stack traces, and bisect recent changes.
Q49. What are workers in JavaScript used for?
Answer: Workers run scripts off the main thread via message passing. Dedicated workers for CPU-heavy tasks; service workers for offline/caching/push; shared workers across tabs of an origin. Workers cannot touch the DOM directly.
Q50. How does JavaScript garbage collection work?
Answer: Engines reclaim unreachable objects, typically with mark-and-sweep and generational heuristics. Roots include globals and the call stack; anything unreachable is collected. Closures, detached DOM nodes, and forgotten timers are common leak sources.
Q51. How do you check the data type of a variable?
Answer: typeof works for primitives (with typeof null === 'object' as the classic quirk). Use Array.isArray for arrays, value === null for null, and instanceof or Object.prototype.toString.call for richer object tagging.
Q52. How do you convert a string to a number in JavaScript?
Answer: Number(str) or unary +str for full-string conversion; parseInt(str, radix) and parseFloat(str) parse prefixes. Watch for NaN on bad input and always pass radix 10 to parseInt.
Q53. What are template literals and how are they used?
Answer: Backtick strings support ${expression} interpolation and multi-line text. Prefer them over concatenation for readability. Tagged templates pass the parts to a function for custom parsing (e.g. sanitization, i18n).
Q54. Explain the concept of tagged templates
Answer: A tag is a function called as tag`Hello ${name}!`, receiving the string chunks and interpolated values separately. Libraries use this for safe HTML, SQL-ish DSLs, and styled-components-style CSS.
Q55. What is the purpose of the break and continue statements?
Answer: break exits the nearest loop or switch early. continue skips the rest of the current iteration and moves to the next. Labeled break/continue can target outer loops when nested.
Q56. What is the ternary operator and how is it used?
Answer: condition ? ifTrue : ifFalse chooses an expression. Great for simple assignments; nest sparingly for readability. Prefer if/else for multi-branch logic.
Q57. How do you access the index of an element during array iteration?
Answer: forEach/map callbacks receive (item, index). for...of with array.entries() yields [index, value]. Classic indexed for loops expose the index directly.
Q58. What is the purpose of the switch statement?
Answer: switch compares an expression against case labels (strict equality) and runs the matching branch. Use break (or return) to avoid fall-through unless intentional. default covers unmatched values.
Q59. What are rest parameters and how are they used?
Answer: function f(...args) gathers remaining arguments into a real array. Prefer rest over the arguments object. Also works in destructuring: const [first, ...rest] = arr.
Q60. What is the difference between a parameter and an argument?
Answer: Parameters are the named placeholders in a function definition. Arguments are the concrete values supplied at the call site.
Q61. Can you offer a use case for the arrow function syntax?
Answer: Arrows shine as short callbacks (map/filter) and anywhere lexical this is desired (React class field handlers historically, nested callbacks). Avoid arrows when you need a constructable function or dynamic this.
Q62. What are callback functions and how are they used?
Answer: A callback is a function passed to be invoked later — on success, on an event, or per item. Foundation of Node-style APIs and array methods; today often wrapped by Promises for sequencing and errors.
Q63. What is recursion and how is it used in JavaScript?
Answer: A recursive function calls itself with a smaller subproblem until a base case. Useful for trees, DFS, and divide-and-conquer. Mind stack depth; convert to loops or trampolines for deep inputs.
Q64. What are default parameters and how are they used?
Answer: function greet(name = 'Guest') assigns defaults when the argument is missing or undefined (not null). Defaults are evaluated at call time and can reference earlier parameters.
Q65. Explain why function foo(){}(); is not an IIFE and how to fix it
Answer: The parser treats function foo(){} as a declaration, so the trailing () is a syntax error. Wrap the function in parentheses to make an expression: (function foo(){})(); or (() => {})();.
Q66. Explain the difference between dot notation and bracket notation
Answer: obj.prop needs a valid identifier known at write time. obj[expr] evaluates a string/symbol key — required for dynamic keys, kebab-case names, or symbols.
Q67. How do you add, remove, and update elements in an array?
Answer: Add with push/unshift/splice or immutable [...arr, x]. Remove with pop/shift/splice/filter. Update by index assignment or map for immutable updates. Prefer non-mutating patterns in React state.
Q68. What are the different ways to copy an object or an array?
Answer: Shallow: spread, Object.assign, Array.from, slice. Deep: structuredClone (preferred modern built-in), or JSON parse/stringify with limitations (no functions, Dates become strings, etc.).
Q69. Explain the difference between shallow copy and deep copy
Answer: Shallow copy duplicates only the top level; nested objects/arrays are still shared references. Deep copy recursively clones nested structures so mutations do not affect the original.
Q70. How do you check if an object has a specific property?
Answer: Object.hasOwn(obj, key) or Object.prototype.hasOwnProperty.call for own keys. key in obj also finds inherited enumerable properties. Prefer hasOwn for own-property checks.
Q71. Explain destructuring assignment for objects and arrays
Answer: const [a, b] = arr and const { name, age } = obj unpack into variables. Supports defaults, renaming ({ name: n }), nested patterns, and rest. Widely used in function params.
Q72. What is Object.freeze() for?
Answer: freeze makes an object shallowly immutable: no add/remove/reassign of own properties. Nested objects remain mutable unless frozen too. In non-strict mode, writes fail silently.
Q73. What is Object.seal() for?
Answer: seal prevents adding or deleting properties and marks existing ones non-configurable, but still allows changing writable values. Stricter than preventExtensions, looser than freeze.
Q74. What is Object.preventExtensions() for?
Answer: It blocks adding new properties but still allows deleting and modifying existing ones. Least restrictive of the three integrity methods.
Q75. How do you reliably determine whether an object is empty?
Answer: For plain objects, Object.keys(obj).length === 0 (or check symbols too if needed). For Maps/Sets use .size === 0. Remember arrays and null are not empty plain objects.
Q76. Explain the concept of a callback function in asynchronous operations
Answer: Async APIs accept a function to run when the operation finishes, keeping the main thread free. Error-first Node callbacks and DOM listeners are classic forms; Promises build on the same idea with better composition.
Q77. What are Promises and how do they work?
Answer: A Promise represents a future value: pending, then fulfilled or rejected. Consumers attach then/catch/finally (or await). Settled promises are immutable; chaining returns new promises for sequencing.
Q78. Explain the different states of a Promise
Answer: pending → fulfilled with a value, or pending → rejected with a reason. A promise settles once. Attaching handlers after settlement still runs them (as microtasks).
Q79. What is the use of Promise.all()?
Answer: Promise.all(iterable) fulfills with an array of results when every input fulfills, or rejects on the first rejection (fail-fast). Ideal for parallel independent requests that all must succeed.
Q80. How is Promise.all() different from Promise.allSettled()?
Answer: all fails fast on first rejection. allSettled waits for every promise and returns { status, value|reason } per item — better when you want partial success reporting.
Q81. What is async/await and how does it simplify asynchronous code?
Answer: async functions always return Promises. await pauses the async function until a Promise settles, writing async flows in linear style with try/catch. It is syntactic sugar over Promises, not a new concurrency model.
Q82. How do you handle errors in asynchronous operations?
Answer: With async/await use try/catch/finally. With Promise chains use .catch. Always handle rejections; for fetch also check response.ok. Propagate meaningful errors instead of swallowing them.
Q83. Explain the concept of a microtask queue
Answer: Microtasks (Promise jobs, queueMicrotask, MutationObserver) drain completely after the current turn and before the next macrotask/rendering opportunity. That priority explains many surprising ordering interview questions.
Q84. What is the difference between setTimeout(), setImmediate(), and process.nextTick()?
Answer: In browsers, setTimeout schedules a macrotask after a delay. In Node, process.nextTick runs before the next event-loop phase (can starve I/O if abused); setImmediate runs on the check phase. Prefer setTimeout for portable delayed work; know Node-specific APIs only in Node.
Q85. What is the prototype chain and how does it work?
Answer: Lookup walks obj → [[Prototype]] → … → null. Methods live on shared prototypes so instances stay light. Object.getPrototypeOf / Object.setPrototypeOf inspect and adjust the link (setPrototypeOf sparingly for performance).
Q86. Explain the difference between classical inheritance and prototypal inheritance
Answer: Classical models copy/extend class blueprints into instances. JavaScript links objects to other objects (delegation). class syntax looks classical but still builds a prototype chain underneath.
Q87. Explain inheritance in ES2015 classes
Answer: class Child extends Parent { constructor(...) { super(...); } } sets up the prototype link and calls the parent constructor. Override methods and use super.method() to reuse parent behavior.
Q88. What is the purpose of the new keyword?
Answer: new creates an object, sets its prototype from constructor.prototype, binds this for the constructor call, and returns that object (unless the constructor returns a different object).
Q89. How do you create a constructor function?
Answer: Declare a capitalized function, assign instance fields on this, put shared methods on Fn.prototype, and call with new. Prefer class syntax for clarity in modern codebases.
Q90. Explain the concept of lexical scoping
Answer: Scope is determined by where functions/blocks are written, not where they are called. Inner functions see outer bindings — the foundation of closures.
Q91. Explain the concept of scope in JavaScript
Answer: Global scope is shared; function scope applies to var and function declarations; block scope applies to let/const/class inside {}. Modules have their own top-level scope.
Q92. How can closures be used to create private variables?
Answer: Keep state in an outer function/module and expose only methods that close over it. External code cannot touch the closed-over bindings directly — classic module and factory patterns.
Q93. What are the potential pitfalls of using closures?
Answer: They retain referenced memory until unused, can surprise you in loops with var, and make stacks harder to reason about if overused. Prefer let in loops and drop references when done.
Q94. Explain the different ways the this keyword can be bound
Answer: Default (global/undefined), implicit (method receiver), explicit (call/apply/bind), new-binding, and lexical (arrows). When rules compete, new and bind generally win over implicit; arrows ignore the others.
Q95. What are the common pitfalls of using this?
Answer: Losing this when passing methods as bare callbacks, nested regular functions inside methods, and mixing arrows where dynamic this was expected. Fix with bind, arrows, or wrapping calls.
Q96. Explain this binding in event handlers
Answer: In addEventListener with a regular function, this is the element. Arrow handlers inherit outer this instead. class fields as arrows capture the instance; bound methods do too.
Q97. What is the DOM and how is it structured?
Answer: The Document Object Model is a tree of nodes (elements, text, etc.) representing the page. Scripts read/update structure, attributes, and content through DOM APIs.
Q98. What's the difference between an attribute and a property in the DOM?
Answer: Attributes are HTML source values; properties are live JS fields on the DOM object. Example: value attribute is the initial value; input.value property tracks the current user input.
Q99. Explain document.querySelector vs document.getElementById
Answer: getElementById('id') is a fast ID lookup. querySelector(css) finds the first match for any CSS selector. Use getElementById for simple IDs; querySelector for classes, attributes, and complex selectors.
Q100. How do you add, remove, and modify HTML elements using JavaScript?
Answer: createElement + append/appendChild to add; remove()/removeChild to delete; textContent/innerHTML/classList/setAttribute to modify. Prefer textContent when you do not intentionally inject HTML.
Q101. What are event listeners and how are they used?
Answer: element.addEventListener(type, handler, options) registers callbacks for clicks, input, etc. Remove with removeEventListener using the same function reference. Options include once, capture, and passive.
Q102. Explain the event phases in a browser
Answer: Capturing (root → target), target, then bubbling (target → root). Listeners choose capture vs bubble via the third argument/options. Understanding phases is key to delegation and stopPropagation.
Q103. How do you prevent the default behavior of an event?
Answer: Call event.preventDefault() in the handler — e.g. to stop form submit or link navigation. It does not stop propagation by itself.
Q104. What is the difference between event.preventDefault() and event.stopPropagation()?
Answer: preventDefault cancels the browser's default action. stopPropagation stops the event from reaching other listeners on ancestors (or further along the path). They solve different problems.
Q105. What is the difference between innerHTML and textContent?
Answer: innerHTML parses HTML markup (XSS risk with untrusted strings). textContent sets/gets plain text without parsing tags. Prefer textContent or safe APIs when rendering user data.
Q106. How do you manipulate CSS styles using JavaScript?
Answer: Use element.style for inline tweaks, or classList.add/remove/toggle for stylesheet-driven changes (preferred). getComputedStyle reads the final cascaded styles.
Q107. What is the difference between the Window object and the Document object?
Answer: window is the global browsing context (timers, location, history, frames). document is the DOM tree loaded in that window. document is typically reached as window.document.
Q108. How do you make an HTTP request using the Fetch API?
Answer: fetch(url, options) returns a Promise of Response. Check response.ok, then response.json()/text(). Pass method, headers, and body for POST/PUT. Handle network errors in catch and HTTP errors via status checks.
Q109. What are the different ways to make an API call in JavaScript?
Answer: fetch (standard), XMLHttpRequest (legacy), and libraries like Axios. In Node you also have native fetch or HTTP clients. Prefer fetch unless you need Axios interceptors or broad legacy support.
Q110. Explain how JSONP works and why it's not really Ajax
Answer: JSONP injects a <script> whose URL returns callback({...data...}), bypassing same-origin limits for GET-only data. It is not XHR/fetch, cannot use POST safely, and is largely obsolete thanks to CORS.
Q111. Explain the concept of the WebSocket API
Answer: WebSocket opens a persistent full-duplex connection (ws/wss) for low-latency bidirectional messages — chats, multiplayer, live feeds. Contrast with HTTP request/response and one-way SSE.
Q112. How do you detect if JavaScript is disabled on a page?
Answer: You cannot run JS to detect that JS is off. Provide <noscript> fallback content and build critical paths to degrade gracefully without scripting.
Q113. What is the Intl namespace object for?
Answer: Intl provides locale-aware formatting: DateTimeFormat, NumberFormat, RelativeTimeFormat, Collator, and more. Prefer it over hand-rolled date/number strings for i18n.
Q114. How do you validate form elements using the Constraint Validation API?
Answer: Use required/pattern/min/max attributes plus checkValidity(), reportValidity(), setCustomValidity(), and the validity object. Combines native UI with custom messages.
Q115. How do you use the window.history API?
Answer: history.pushState/replaceState update the URL and history stack without reloads; popstate fires on back/forward. Foundation of client-side routing in SPAs.
Q116. How do iframes on a page communicate?
Answer: Use window.postMessage with an explicit targetOrigin, and verify event.origin on the receiving side. Never accept messages from untrusted origins blindly.
Q117. Difference between document load and DOMContentLoaded?
Answer: DOMContentLoaded fires when HTML is parsed (stylesheets/images may still load). window load fires after dependent resources finish. Prefer DOMContentLoaded for early DOM setup.
Q118. How do you redirect to a new page in JavaScript?
Answer: location.href = url or location.assign(url) navigates and keep history; location.replace(url) navigates without adding a history entry. Prefer server redirects for SEO-critical flows when possible.
Q119. How do you get the query string values of the current page?
Answer: const params = new URLSearchParams(location.search); params.get('key'). Also URL/searchParams on full URLs. Avoid manual string splitting.
Q120. What are Progressive Web Applications (PWAs)?
Answer: PWAs use HTTPS, a web app manifest, and usually a service worker to feel installable, work offline/cached, and sometimes support push. They bridge web reach and app-like UX.
Q121. What are modules and why are they useful?
Answer: Modules encapsulate code with explicit imports/exports, avoiding global pollution and clarifying dependencies. They enable bundling, tree-shaking, and clearer ownership boundaries.
Q122. How do you import and export modules in JavaScript?
Answer: Named: export const x; import { x } from './mod.js'. Default: export default ...; import Name from './mod.js'. Dynamic import() returns a Promise for code-splitting.
Q123. What are the benefits of using a module bundler?
Answer: Bundlers resolve dependencies, split code, tree-shake, transpile, and fingerprint assets for caching. They turn many modules into optimized browser-ready files.
Q124. Explain tree shaking in module bundling
Answer: Tree shaking drops unused ESM exports based on static analysis. Needs ES modules and side-effect-aware package metadata. Dead CommonJS is much harder to eliminate.
Q125. What are the metadata fields of a module?
Answer: In package.json: name, version, description, license, dependencies/peerDependencies, type/module/exports fields, and engines. They describe identity and how tools consume the package.
Q126. What do you think of CommonJS vs ESM?
Answer: ESM is the language standard with static structure and native browser support. CommonJS remains common in older Node packages. New libraries should ship ESM (dual-publish if needed).
Q127. What are the different types of errors in JavaScript?
Answer: Syntax errors prevent parsing; runtime errors throw during execution (TypeError, ReferenceError, etc.); logic errors produce wrong results without throwing. Custom Error subclasses express domain failures.
Q128. How do you handle errors using try...catch blocks?
Answer: Wrap risky sync/await code in try, handle in catch, and put cleanup in finally. catch only synchronous throws and awaited rejections inside the try — not errors in detached Promise chains.
Q129. What is the purpose of the finally block?
Answer: finally always runs after try/catch — success or failure — for cleanup like closing resources or stopping spinners. Be careful returning from finally; it can override earlier returns/throws.
Q130. How can you create custom error objects?
Answer: class MyError extends Error { constructor(message) { super(message); this.name = 'MyError'; } }. Throw and catch by class for precise handling.
Q131. Explain the concept of error propagation in JavaScript
Answer: Unhandled exceptions bubble up the call stack until caught or reported as uncaught. Async errors propagate through Promise rejections. Catch at boundaries (UI, request handlers) and rethrow when you cannot recover.
Q132. What is currying and how does it work?
Answer: Currying turns f(a,b,c) into f(a)(b)(c) — one argument per function. Enables reusable partially configured functions in a functional style.
Q133. Explain the concept of partial application
Answer: Partial application fixes some arguments now and returns a function awaiting the rest — e.g. add.bind(null, 5). Related to currying but can fix multiple args at once without requiring unary steps.
Q134. How do currying and partial application differ?
Answer: Currying always decomposes into unary nested functions. Partial application produces a function with fewer remaining parameters and does not require arity-one steps.
Q135. What are Sets and Maps and how are they used?
Answer: Set stores unique values; Map stores key/value pairs with any key type. Both are iterable and excel at membership checks and frequent updates versus hand-rolled object dictionaries.
Q136. How do you convert a Set to an array in JavaScript?
Answer: Use [...mySet] or Array.from(mySet). The reverse is new Set(array) for deduplication.
Q137. How do Sets and Maps handle equality checks for objects?
Answer: They use SameValueZero equality: objects compare by reference, not deep structure. Two different {a:1} literals are distinct keys/entries.
Q138. What are some common performance bottlenecks in JavaScript applications?
Answer: Layout thrashing, excessive DOM work on the main thread, huge bundles, unoptimized images/network waterfalls, memory leaks, and chatty re-renders. Profile before optimizing.
Q139. Explain the concept of debouncing and throttling
Answer: Debounce waits until calls pause for N ms (search-as-you-type). Throttle runs at most once per N ms (scroll/resize). Both cut down expensive handlers under rapid events.
Q140. How can you optimize DOM manipulation for better performance?
Answer: Batch reads then writes, use DocumentFragment, minimize reflows, prefer class toggles over many inline styles, and virtualize long lists. Frameworks help via virtual DOM/compilers, but discipline still matters.
Q141. What are some techniques for reducing reflows and repaints?
Answer: Avoid interleaving measure/mutate loops, change classes in batches, use transform/opacity for animations, and apply contain/content-visibility where appropriate. Read layout properties sparingly.
Q142. Explain lazy loading and how it can improve performance
Answer: Lazy loading defers work until needed — images with loading="lazy", dynamic import() for routes/components, and on-demand data. Improves initial load and time-to-interactive.
Q143. What are Web Workers and how can they improve performance?
Answer: Move CPU-heavy computation to a dedicated worker so the UI thread stays responsive. Communicate with postMessage/structured clone; keep payloads efficient.
Q144. Explain caching and how it can improve performance
Answer: Caching stores responses/assets closer to the user (browser HTTP cache, service workers, memory/CDN). Correct Cache-Control and invalidation strategies prevent serving stale or uncached data.
Q145. What are some tools to measure and analyze JavaScript performance?
Answer: Chrome Performance/Lighthouse, WebPageTest, React Profiler, and microbenchmarks for hotspots. Measure Core Web Vitals and real-user monitoring in production when possible.
Q146. How can you optimize network requests for better performance?
Answer: Fewer requests, HTTP/2/3, compression, caching, CDN, code-splitting, prefetch/preconnect, and right-sized payloads (pagination, gzip/brotli). Avoid waterfalls by parallelizing independent fetches.
Q147. What are the different types of testing in software development?
Answer: Unit, integration, end-to-end, plus broader QA like regression, performance, and acceptance testing. Each layer catches different failure modes.
Q148. Explain unit vs integration vs end-to-end testing
Answer: Unit tests isolate small pure units. Integration tests verify modules collaborating (API + DB, component + hook). E2E drives the real UI/browser through user journeys. Pyramid: many fast unit tests, fewer E2E.
Q149. What are some popular JavaScript testing frameworks?
Answer: Jest and Vitest for unit/integration; Testing Library for UI assertions; Playwright/Cypress for E2E; Mocha/Jasmine in older stacks. Pick based on speed, ESM support, and browser needs.
Q150. How do you write unit tests for JavaScript code?
Answer: Arrange inputs, act by calling the unit, assert outputs/side effects. Keep tests deterministic; mock I/O boundaries. Name tests by behavior, not implementation trivia.
Q151. Explain test-driven development (TDD)
Answer: Red-green-refactor: write a failing test, implement the minimum to pass, then clean up. Improves design feedback and regression safety when applied pragmatically.
Q152. What are mocks and stubs and how are they used in testing?
Answer: Stubs provide canned responses; mocks also assert how they were called. Use them to isolate units from network/DB/time. Prefer real collaborators in higher-level tests.
Q153. How can you test asynchronous code in JavaScript?
Answer: Return Promises or use async/await in tests; await the assertion. For callbacks, use the framework's done or wrap in a Promise. Advance fake timers for debounce/throttle logic.
Q154. What are some best practices for writing maintainable tests?
Answer: Test behavior, keep tests independent, use clear names, avoid brittle selectors, and share setup carefully. Delete or rewrite tests that only mirror implementation.
Q155. Explain code coverage and how it assesses test quality
Answer: Coverage shows which lines/branches ran during tests — useful for finding gaps, not a guarantee of correctness. Aim for meaningful scenarios over chasing 100%.
Q156. What are design patterns and why are they useful?
Answer: Named, reusable solutions to recurring design problems. They share vocabulary across teams and help structure code — use them when they clarify, not as cargo cult.
Q157. Explain the Singleton pattern
Answer: Singleton ensures one shared instance. In JS, ES modules are often naturally single-instance. Be wary of hidden global state and testing pain.
Q158. What is the Factory pattern and how is it used?
Answer: A factory function/class creates objects without exposing new/concrete types to callers — helpful when creation logic varies by input or environment.
Q159. Explain the Observer pattern and its use cases
Answer: Subjects notify registered observers of changes — the backbone of events, Rx-style streams, and UI reactivity. Decouples producers from many consumers.
Q160. What is the Module pattern and how does it help with encapsulation?
Answer: Historically an IIFE returning a public API while closing over private state. Today ES modules provide clearer encapsulation with real privacy (and #private fields in classes).
Q161. Explain the Prototype pattern
Answer: Create new objects by cloning a prototype instance (Object.create or structured copy) when setup is expensive or variants share structure.
Q162. What is the Decorator pattern and how is it used?
Answer: Wrap an object/function to add behavior without modifying the original — higher-order functions, middleware, and class decorators (where supported) follow this idea.
Q163. Explain the Strategy pattern
Answer: Encapsulate interchangeable algorithms behind a common interface and inject the one you need (sort strategies, payment methods). Avoids sprawling conditionals.
Q164. What is the Command pattern and how is it used?
Answer: Package an action as an object with execute (and maybe undo) — useful for queues, macros, and undo stacks in editors.
Q165. What is Cross-Site Scripting (XSS) and how can you prevent it?
Answer: XSS injects attacker script into pages viewed by others. Prevent by escaping/encoding output, avoiding unsafe innerHTML, sanitizing HTML, using CSP, and treating all user input as untrusted.
Q166. Explain CSRF and its mitigation techniques
Answer: CSRF tricks a logged-in browser into sending unwanted authenticated requests. Mitigate with anti-CSRF tokens, SameSite cookies, careful CORS, and avoiding cookie auth for state-changing APIs without extra checks.
Q167. How can you prevent SQL injection in JavaScript applications?
Answer: Never concatenate untrusted input into SQL. Use parameterized queries/prepared statements or trusted ORMs, plus validation and least-privilege DB users.
Q168. What are some best practices for handling sensitive data in JavaScript?
Answer: Do not put secrets in frontend code or localStorage if XSS is a risk. Use HTTPS, httpOnly secure cookies or careful token storage, short-lived tokens, and server-side encryption for secrets at rest.
Q169. Explain Content Security Policy (CSP) and how it enhances security
Answer: CSP headers/meta tell the browser which sources may load scripts, styles, etc., reducing XSS impact. Start in report-only, then enforce; avoid unsafe-inline when possible.
Q170. What are some common security headers and their purpose?
Answer: CSP, Strict-Transport-Security, X-Content-Type-Options, Referrer-Policy, Permissions-Policy, and frame-ancestors/X-Frame-Options. They harden browsers against XSS, sniffing, clickjacking, and mixed content.
Q171. How can you prevent clickjacking attacks?
Answer: Disallow framing with Content-Security-Policy: frame-ancestors 'none'/'self' or X-Frame-Options. Combine with UI confirmations for sensitive actions.
Q172. Explain input validation and its importance in security
Answer: Validate and sanitize on the server (client checks are UX only). Enforce types, lengths, and allowlists to block injection and broken business logic.
Q173. What are some tools for identifying security vulnerabilities in JavaScript code?
Answer: npm audit/OSV, ESLint security plugins, SAST/DAST (e.g. OWASP ZAP), dependency pinning/updates, and threat-modeling reviews for auth and data flows.
Q174. How can you implement secure authentication and authorization in JavaScript applications?
Answer: Use proven libraries (OAuth/OIDC, Auth.js, etc.), HTTPS everywhere, hashed passwords server-side, short-lived access tokens, refresh rotation, and server-enforced authorization checks on every sensitive action.
Q175. Explain the same-origin policy with regards to JavaScript
Answer: Browsers isolate document access by scheme+host+port. Cross-origin reads are blocked unless CORS (or other mechanisms) allow them. It is a cornerstone of web security.
Q176. Explain what a single page app is and how to make one SEO-friendly
Answer: An SPA loads a shell and routes client-side. For SEO, prefer SSR/SSG/ISR or hybrid rendering (Next.js, Nuxt, etc.) so crawlers receive meaningful HTML, plus correct metadata and crawlable URLs.
Q177. How can you share code between JavaScript files?
Answer: Export/import via ES modules (or require in CJS). Share types via .d.ts/TypeScript projects. Avoid copy-paste and avoid dumping shared helpers on window.
Q178. How do you organize your code?
Answer: Group by feature or layer (UI, domain, data), keep modules small, enforce lint/format, and document public boundaries. Consistency beats perfect taxonomy.
Q179. What are advantages and disadvantages of TypeScript and compile-to-JS languages?
Answer: Pros: earlier errors, better editor tooling, clearer APIs. Cons: build complexity, learning curve, and occasional type gymnastics. TypeScript is the mainstream choice for large apps.
Q180. When would you use document.write()?
Answer: Almost never in modern apps — after load it can wipe the document. Prefer DOM APIs or frameworks. You may see it only in legacy snippets or demos.
Q181. Explain the difference in hoisting between var, let, and const
Answer: All three are hoisted in the sense the binding exists for the scope, but var is initialized to undefined immediately while let/const remain uninitialized until evaluated (TDZ). const also requires an initializer.
Q182. How does hoisting affect function declarations and expressions?
Answer: Declarations are callable before their line. Expressions assigned to var/let/const are not usable as functions until the assignment runs — early access yields undefined (var) or TDZ errors (let/const).
Q183. What are the potential issues caused by hoisting?
Answer: Unexpected undefined values, TDZ ReferenceErrors, and confusion when declarations are scattered. Temporal assumptions make bugs harder to spot in large functions.
Q184. How can you avoid problems related to hoisting?
Answer: Prefer const/let, declare before use, avoid var, and rely on modules/block scope. Linters (no-use-before-define) catch many issues.
Q185. Explain the concept of hoisting with regards to functions
Answer: Function declarations hoist with their body. Function expressions and arrows follow variable rules. Class declarations are in the TDZ like let.
Q186. Provide some examples of how currying and partial application can be used
Answer: Currying: const add = a => b => a + b; const add5 = add(5). Partial: const add5 = (a,b) => a+b; const add5p = add.bind(null,5) or a helper that pre-fills args for logging/config.
Q187. What are the benefits of using currying and partial application?
Answer: They produce specialized reusable functions, improve composition, and clarify pipelines — at the cost of more indirection if overused.
Q188. What are the advantages of using the spread operator with arrays and objects?
Answer: Readable cloning/merging, easier immutable updates, and simple argument expansion. Remember spreads are shallow copies.
Q189. What are the different methods for iterating over an array?
Answer: for, for...of, forEach, map/filter/reduce/some/every/find. Choose map/filter for transformations, for/for...of when you need break or async await in a straightforward loop.