Skip to main content

Amazon Interview JavaScript Interview Questions

Curated Amazon Interview-level JavaScript interview questions for developers targeting amazon interview positions. 140 questions available.

Last updated:

JavaScript Interview Questions & Answers

Skip to Questions

Welcome to our comprehensive collection of JavaScript interview questions and answers. This page contains expertly curated interview questions covering all aspects of JavaScript, from fundamental concepts to advanced topics. Whether you're preparing for an entry-level position or a senior role, you'll find questions tailored to your experience level.

Our JavaScript interview questions are designed to help you:

  • Understand core concepts and best practices in JavaScript
  • Prepare for technical interviews at all experience levels
  • Master both theoretical knowledge and practical application
  • Build confidence for your next JavaScript interview

Each question includes detailed answers and explanations to help you understand not just what the answer is, but why it's correct. We cover topics ranging from basic JavaScript concepts to advanced scenarios that you might encounter in senior-level interviews.

Use the filters below to find questions by difficulty level (Entry, Junior, Mid, Senior, Expert) or focus specifically on code challenges. Each question is carefully crafted to reflect real-world interview scenarios you'll encounter at top tech companies, startups, and MNCs.

Questions

140 questions
Q1:

What is JavaScript and where is it used?

Entry

Answer

JavaScript is a high-level, interpreted programming language used to create interactive web pages.

  • Runs on browsers for client-side scripting.
  • Used on servers via Node.js.
  • Powers mobile, desktop, and game applications.
Quick Summary: JavaScript is a dynamic, interpreted programming language originally designed for the browser. Today it runs everywhere — browsers (DOM manipulation, SPAs), servers (Node.js), mobile (React Native), and desktop (Electron). It's the only language that runs natively in every browser, making it the universal language of the web.
Q2:

Difference between var, let, and const.

Entry

Answer

  • var: function-scoped, redeclarable, hoisted with undefined.
  • let: block-scoped, cannot redeclare in same scope, hoisted but uninitialized.
  • const: block-scoped, cannot reassign, must initialize.
Quick Summary: var is function-scoped and hoisted — can be redeclared, accessible before declaration (as undefined). let is block-scoped, not hoisted in a usable way, can be reassigned but not redeclared. const is block-scoped, can't be reassigned. Prefer const by default, use let when you need to reassign, avoid var in modern code.
Q3:

What is hoisting in JavaScript?

Entry

Answer

Hoisting moves variable and function declarations to the top of their scope before execution. Only declarations are hoisted, not initializations.

Quick Summary: Hoisting moves declarations to the top of their scope during compile time — before code runs. var declarations and function declarations are hoisted. var is initialized as undefined; function declarations are fully hoisted (callable before they appear). let and const are hoisted but not initialized — accessing them before declaration throws a ReferenceError (temporal dead zone).
Q4:

Difference between synchronous and asynchronous execution.

Entry

Answer

Synchronous: Executes line-by-line and blocks.

Asynchronous: Non-blocking; uses callbacks, promises, async/await.

Quick Summary: Synchronous: each operation runs in order, one at a time — the next line waits for the current one to finish. Asynchronous: an operation starts and the code continues without waiting — when the operation completes, a callback or Promise resolves. JavaScript is single-threaded, so async is essential for I/O (network, file) without blocking the main thread.
Q5:

What is a closure?

Entry

Answer

A closure is a function that retains access to its lexical scope even after the outer function has returned.

Quick Summary: A closure is a function that remembers the variables from its outer scope even after the outer function has returned. The inner function "closes over" those variables. Common use: factory functions, data privacy (like private variables), and callbacks that need access to loop variables. Every function in JavaScript is a closure.
Q6:

What are data types in JavaScript?

Entry

Answer

Primitive: String, Number, Boolean, Null, Undefined, Symbol, BigInt.

Non-primitive: Object, Array, Function.

Quick Summary: JavaScript has: Primitive types — string, number, bigint, boolean, null, undefined, symbol. And Object type — including arrays, functions, dates, and plain objects. Primitives are immutable and compared by value. Objects are compared by reference — two separate objects with the same content are not equal.
Q7:

Difference between == and ===.

Entry

Answer

== compares values with type coercion.

=== compares value and type strictly. Prefer strict equality.

Quick Summary: == does loose equality with type coercion — "5" == 5 is true because JS converts the string to a number. === does strict equality with no coercion — "5" === 5 is false because types differ. Always use === in modern code to avoid the subtle bugs that type coercion introduces.
Q8:

What is the event loop?

Entry

Answer

The event loop handles asynchronous callbacks, allowing JavaScript to remain non-blocking despite being single-threaded.

Quick Summary: The event loop is JavaScript's concurrency mechanism. It continuously checks: is the call stack empty? If yes, take the next task from the callback queue (macrotasks) or microtask queue (Promises). Microtasks run before macrotasks. This single-threaded loop is how JS handles async operations without blocking.
Q9:

Difference between null and undefined.

Entry

Answer

null: explicitly assigned to indicate no value.

undefined: declared but not assigned.

Quick Summary: null is an intentional absence of value — you explicitly set it. undefined means a variable was declared but not yet assigned, or a function returns nothing, or an object property doesn't exist. typeof null is "object" (a famous JS bug). typeof undefined is "undefined". Both are falsy.
Q10:

What are first-class functions?

Entry

Answer

Functions in JavaScript are treated as values, enabling assignment, passing as arguments, and returning from functions.

Quick Summary: First-class functions means functions are values in JavaScript — they can be stored in variables, passed as arguments, returned from other functions, and put in arrays or objects. This enables higher-order functions, callbacks, and functional programming patterns. It's what makes setTimeout(fn, 1000) work — fn is just a value.
Q11:

Difference between function declaration and function expression.

Entry

Answer

Declaration is hoisted and callable before definition; expression is assigned at runtime and not hoisted the same way.

Quick Summary: Function declaration: function greet() {} — hoisted completely, can be called before it's defined in the file. Function expression: const greet = function() {} — not hoisted, only available after the assignment. Arrow functions are expressions too. Declarations are good for named utilities; expressions are better for callbacks and closures.
Q12:

What is the this keyword?

Entry

Answer

this refers to current execution context. Arrow functions inherit this from their parent scope.

Quick Summary: this refers to the context in which a function is called. In a method: this is the object. In a regular function: this is window (or undefined in strict mode). In arrow functions: this is inherited from the enclosing scope (lexical this). In event handlers: this is the element. The value of this is determined by how the function is invoked, not where it's defined.
Q13:

Difference between call, apply, and bind.

Entry

Answer

  • call: invoke with arguments list.
  • apply: invoke with arguments array.
  • bind: returns a new function with bound this.
Quick Summary: All three invoke a function with a specific this value. call(thisArg, arg1, arg2): invokes immediately with individual args. apply(thisArg, [args]): invokes immediately with args as an array. bind(thisArg, arg1): returns a new function with this permanently bound — call it later. Use bind for event handlers and callbacks where this would otherwise be lost.
Q14:

What is prototype in JavaScript?

Entry

Answer

Every object has a prototype from which it can inherit methods and properties.

Quick Summary: Every JavaScript object has a prototype — an object it inherits from. When you access a property, JS looks at the object first, then follows the prototype chain upward until it finds it or reaches null. Array.prototype has push, map, filter. Object.prototype has toString, hasOwnProperty. This chain is how inheritance works in JS.
Q15:

Difference between ES5 and ES6.

Entry

Answer

ES6 adds let/const, arrow functions, classes, modules, promises, destructuring, template literals, and more.

Quick Summary: ES6 (ES2015) added: let/const, arrow functions, template literals, destructuring, default parameters, rest/spread operators, classes, Promises, modules (import/export), Map/Set, Symbol, generators, and iterators. ES5 used var, function expressions, string concatenation, and no native module system. ES6 made JavaScript dramatically more expressive and modern.
Q16:

What are promises?

Entry

Answer

Promises represent asynchronous results with states: pending, fulfilled, rejected.

Quick Summary: A Promise represents the eventual result of an async operation — either resolved (success with a value) or rejected (failure with a reason). It avoids callback hell by enabling .then()/.catch() chaining. A Promise starts pending and settles exactly once. Promises are the foundation of async/await.
Q17:

Explain async/await.

Entry

Answer

Async/await simplifies working with promises, making asynchronous code readable and sequential.

Quick Summary: async/await is syntactic sugar over Promises. An async function always returns a Promise. await pauses execution inside the async function until the Promise resolves — without blocking the thread. Error handling uses try/catch instead of .catch(). It makes async code read like synchronous code — much cleaner than nested .then() chains.
Q18:

Difference between shallow copy and deep copy.

Entry

Answer

Shallow copy duplicates top-level properties; deep copy recursively duplicates all nested data.

Quick Summary: Shallow copy copies only the top-level properties — nested objects still share the same reference. const copy = {...original} is shallow. Deep copy recursively copies all nested objects — structuredClone(original) or JSON.parse(JSON.stringify(original)) creates fully independent copies. Use deep copy when you need to modify nested data without affecting the original.
Q19:

What is the difference between let inside and outside loops?

Entry

Answer

Inside loop, let creates a new binding for each iteration, preventing closure-related bugs.

Quick Summary: let inside a loop creates a new binding for each iteration — closures inside the loop capture their own independent copy of the variable. var inside a loop shares one variable across all iterations — closures capture the same reference. Classic bug: setTimeout inside a for-var loop all see the final value. for-let doesn't have this problem.
Q20:

Explain event delegation.

Entry

Answer

Event delegation uses a single parent listener to manage events for child elements using event bubbling.

Quick Summary: Event delegation attaches one event listener to a parent element instead of individual listeners on every child. The event bubbles up from the clicked child to the parent listener. The listener checks event.target to determine which child was clicked. More efficient for dynamic lists — no need to add/remove listeners as items are added or removed.
Q21:

What is the difference between function scope and block scope?

Entry

Answer

Function scope: Variables declared with var are accessible throughout the function.

Block scope: Variables declared with let or const are limited to the enclosing braces {}.

Block scope reduces bugs and prevents variable leakage.

Quick Summary: Function scope: variables declared with var are accessible anywhere within the containing function, regardless of the block (if, for) they're in. Block scope: variables declared with let or const are only accessible within the {} block they're in. Block scope prevents accidental variable reuse across if/for blocks and eliminates many var-related bugs.
Q22:

Explain closures with real-world usage.

Entry

Answer

A closure is a function that retains access to its outer scope even after the outer function has finished executing.

Use cases: private variables, memoization, function factories, event handlers.

Quick Summary: Closures in real use: a counter factory function returns a function that increments a private count variable — each call creates a new independent counter. Memoization stores results in a closed-over cache object. Module patterns use closures to create private state accessible only through exposed functions. Event handlers close over component state in React hooks.
Q23:

What is the DOM and how does JavaScript interact with it?

Entry

Answer

The DOM represents HTML as objects. JavaScript can select, modify, create, and remove elements using DOM APIs.

Quick Summary: The DOM (Document Object Model) is a tree of objects representing the HTML page. JavaScript interacts with it via document.querySelector(), element.textContent, element.style, element.addEventListener(). Every HTML element becomes a node in the tree. JS reads, modifies, adds, and removes nodes to make pages dynamic without a full reload.
Q24:

Explain event bubbling and capturing.

Entry

Answer

Bubbling: Events propagate from child to parent.

Capturing: Events propagate from parent to child.

Controlled using addEventListener(..., true).

Quick Summary: Event bubbling: an event fires on the target element, then bubbles up through parent elements to the root. Event capturing: the event starts at the root and travels down to the target before bubbling up. addEventListener(event, handler, true) uses capturing phase. Default is bubbling. stopPropagation() prevents the event from continuing up or down the chain.
Q25:

Difference between innerHTML, innerText, and textContent.

Entry

Answer

  • innerHTML: Reads/writes HTML.
  • innerText: Visible text only, respects CSS.
  • textContent: Raw text without parsing HTML.
Quick Summary: innerHTML: gets/sets HTML content — can include tags, but is a security risk (XSS) if set from user input. innerText: gets/sets visible text only — respects CSS visibility and triggers reflow. textContent: gets/sets all text content (including hidden) — doesn't trigger reflow, safer and faster than innerText. Prefer textContent for setting plain text.
Q26:

Explain template literals.

Entry

Answer

Use backticks for multi-line strings and interpolation.

`Hello ${name}`
Quick Summary: Template literals use backticks (`) instead of quotes and allow: multi-line strings (no \\n needed), string interpolation (${expression} is evaluated inline), and tagged templates (a function processes the template). They replace string concatenation ("Hello " + name) with clean, readable `Hello ${name}` syntax.
Q27:

What are arrow functions and how do they differ from regular functions?

Entry

Answer

Arrow functions have shorter syntax, do not have their own this, and cannot be used as constructors.

Quick Summary: Arrow functions: shorter syntax, no own this (inherit from enclosing scope), no arguments object, can't be used as constructors. Regular functions: have their own this (determined by call context), have arguments object, can be constructors. Use arrow functions for callbacks and methods that don't need their own this; regular functions for methods that do.
Q28:

Explain higher-order functions.

Entry

Answer

Functions that receive or return other functions. Used in map, filter, reduce, and event handling.

Quick Summary: Higher-order functions take other functions as arguments or return functions. Built-in examples: map(fn), filter(fn), reduce(fn), forEach(fn). They enable functional programming patterns — composing behavior without loops. A function like debounce(fn, delay) is a higher-order function that returns a new function wrapping fn with delayed execution.
Q29:

What is the difference between map, forEach, and filter?

Entry

Answer

  • forEach: executes callback but returns undefined.
  • map: returns a new transformed array.
  • filter: returns items that match a condition.
Quick Summary: map: returns a new array with each element transformed by the callback. filter: returns a new array with only elements where callback returns true. forEach: just iterates — no return value, no new array. map and filter are chainable; forEach is for side effects. All three don't mutate the original array.
Q30:

Explain setTimeout vs setInterval.

Entry

Answer

setTimeout: runs code once after delay.

setInterval: runs repeatedly at intervals.

Quick Summary: setTimeout(fn, ms): calls fn once after ms milliseconds. setInterval(fn, ms): calls fn repeatedly every ms milliseconds. Both are async — they don't block. The actual delay may be longer than specified (minimum is 0ms, actual depends on event loop state). Always clearInterval(id) to stop a repeating interval, or it runs forever.
Q31:

What is the difference between synchronous and asynchronous DOM manipulation?

Entry

Answer

Synchronous DOM updates block rendering. Asynchronous updates use Promises or requestAnimationFrame to avoid UI jank.

Quick Summary: Synchronous DOM manipulation (direct writes) blocks rendering — the browser can't paint until the JS finishes. Asynchronous DOM manipulation (via requestAnimationFrame or setTimeout(0)) defers the change to the next paint cycle, keeping the UI responsive. For smooth animations, always use requestAnimationFrame — it's synchronized with the browser's display refresh rate.
Q32:

Explain promises and chaining.

Entry

Answer

A promise represents future completion. Chaining uses .then() and .catch() for sequential async workflows.

Quick Summary: Promise chaining: fetch(url).then(r => r.json()).then(data => process(data)).catch(err => handleError(err)). Each .then() receives the resolved value of the previous Promise. .catch() at the end handles any rejection in the chain. Return a value from .then() to pass it to the next link; return a Promise to wait for it.
Q33:

What are the browser storage options in JavaScript?

Entry

Answer

localStorage: persistent key-value.

sessionStorage: session-limited key-value.

cookies: small data sent with requests, used for auth.

Quick Summary: localStorage: persists data across browser sessions (survives tab close), domain-scoped, ~5MB, synchronous API. sessionStorage: same API but cleared when the tab closes. Cookies: small (~4KB), sent with every HTTP request (good for auth tokens), can have expiry. IndexedDB: full client-side database — async, large storage, good for complex offline apps.
Q34:

Difference between synchronous and asynchronous XHR/fetch.

Entry

Answer

Synchronous blocks the main thread; asynchronous uses callbacks/promises and does not block.

Quick Summary: Synchronous XHR blocks the main thread until the server responds — freezes the page. Asynchronous XHR/fetch is non-blocking — the code continues and a callback/Promise fires when the response arrives. Never use synchronous XHR in production. fetch() is the modern, Promise-based replacement for XHR — cleaner API and supports async/await.
Q35:

How do you handle cross-origin requests?

Entry

Answer

Browsers enforce CORS. Servers must send headers allowing specific origins.

Quick Summary: Browsers enforce Same-Origin Policy — your page at domain-a.com can't fetch from domain-b.com without server permission. CORS (Cross-Origin Resource Sharing) headers on the server grant permission: Access-Control-Allow-Origin: * (or specific domain). Preflight OPTIONS requests check permissions for non-simple requests. You can't bypass CORS from the browser — the server must allow it.
Q36:

Explain event delegation and its benefits.

Entry

Answer

Attach listener to parent instead of each child. Better performance and supports dynamic elements.

Quick Summary: Attach one listener to the parent (e.g., a ul) instead of one per child (each li). When a child is clicked, the event bubbles to the parent listener. Use event.target to identify which child triggered it. Benefits: fewer listeners (better memory), handles dynamically added children automatically, cleaner code for large lists.
Q37:

Difference between call, apply, and bind.

Entry

Answer

  • call: invoke with this + args list.
  • apply: invoke with this + args array.
  • bind: returns a new function with bound this.
Quick Summary: call(thisArg, arg1, arg2) and apply(thisArg, [arg1, arg2]) both invoke immediately — call takes args individually, apply takes an array. bind(thisArg) returns a new function permanently bound to that this — not invoked immediately. Use: call/apply for method borrowing, bind for event listeners where this would otherwise be wrong.
Q38:

Difference between == and ===.

Entry

Answer

== compares with coercion; === compares type + value strictly.

Quick Summary: == coerces types before comparing — false == 0 is true, "" == 0 is true, null == undefined is true. === compares type AND value with no coercion — false === 0 is false. Always use === to avoid unexpected coercion. The only common use of == is null == undefined when you want to check for both in one expression.
Q39:

Difference between null and undefined.

Entry

Answer

null: intentional empty value.

undefined: declared but not assigned.

Quick Summary: undefined: variable declared but no value assigned, or missing function return, or missing object property. null: explicitly assigned to mean "no value" — intentional emptiness. typeof undefined is "undefined"; typeof null is "object" (historical bug). null === undefined is false; null == undefined is true.
Q40:

What are IIFEs (Immediately Invoked Function Expressions)?

Entry

Answer

IIFEs run immediately after creation. They isolate scope and avoid global pollution.

Quick Summary: An IIFE is a function that defines and calls itself immediately: (function() { ... })(). It creates a private scope — variables inside don't pollute the global scope. Before ES6 modules, IIFEs were the standard way to encapsulate code. Now replaced by ES modules and block scoping with let/const, but still useful for immediate initialization.
Q41:

Explain ES6 modules and their benefits.

Junior

Answer

ES6 modules allow splitting code into separate files using export and import.

  • Better code organization
  • No global namespace pollution
  • Supports tree shaking for optimized builds
Quick Summary: ES6 modules use import/export to share code between files. Each module has its own scope — no global namespace pollution. Imports are static (analyzable at parse time), enabling tree-shaking. The browser loads them with