JavaScript Interview Questions

JavaScript Interview Questions and Answers

August 5th, 2026
9230
15:00 Minutes

Nailing a JavaScript interview isn't about memorizing definitions. It's about proving you can think in code when someone's watching the clock. And the bar keeps moving. Interviewers aren't just asking "what is a closure" anymore; they're handing you a broken loop and watching how you debug it, or asking you to explain why Promise.allSettled() exists instead of just Promise.all().

That's exactly what this guide is built for. Inside, you will find the most asked JavaScript interview questions and answers, sorted by experience level, from your first junior interview to senior system-design-style rounds. It also includes working code examples, side-by-side comparison tables, and scenario-based debugging problems pulled straight from what companies are actually asking right now.

Whether you're brushing up on the fundamentals (hoisting, this, closures), leveling up on async patterns and the event loop, or prepping for scenario questions like "why does this loop print 5 five times instead of 0 to 4," you can jump straight to the section that matches where you are and start practicing immediately.

Basic JavaScript Interview Questions and Answers

1. What is JavaScript, and where is it used?

JavaScript is an interpreted programming language that enables the creation of interactive and dynamic content on websites. You may have seen various templates and graphics on different websites. Most of them are created using JavaScript. It also has different applications, like:


2. Explain the difference between == and ===.

The == (loose equality) and === (strict equality) operators in JavaScript differ in their handling of type coercion. The loose equality operator compares two values after type coercion to determine whether they are equal. This converts the operands to the same type before comparing them. The strict quality operators compare the values and their types before type conversion.

3. What’s new in ES2025 (ECMAScript 2025)?

Here is what’s new in ECMAScript 2025, the 16th edition of ECMAScript, introduced in June 2025:

Feature Category What It Does Example
Iterator Helpers (map, filter, take, drop, reduce, some, every, toArray, etc.) Iteration improvements Adds chainable, lazy iterator methods for any iterable Iterator.from([1,2,3]).map(x=>x*2).toArray()
Set Methods (union, intersection, difference, symmetricDifference, isSubsetOf, etc.) Data structure upgrades Adds built-in set operations and relationship checks A.union(B)
Import Attributes + JSON Import Module system Let's you import JSON files and use attributes in imports import data from './file.json' with { type:'json' }
RegExp.escape() Regular expressions Safely escapes strings before inserting into regex RegExp.escape("(hello)")
Inline Regex Modifiers Regular expressions Allows enabling/disabling flags for part of a regex /(?i:abc)/
Duplicate Named Capture Groups Regular expressions Allows same same-named group to be used in different alternatives `/(?a)
Promise.try() Promises Wraps sync/async code into a promise in one call Promise.try(() => doSomething())
Float16Array + Float16 Support Typed arrays / Math New 16-bit float type for memory-efficient computation new Float16Array([1.5, 2.5])
DataView getFloat16 / setFloat16 Typed arrays / DataView Allows reading/writing 16-bit floats in DataView dv.getFloat16(offset)
Math.f16round() Math Rounds a number to 16-bit float precision Math.f16round(1.2345)

4. What is the relation between Java and JavaScript?

The name of both programming languages sounds similar, but they are totally different languages. There is no similarity or relation between them. Here is a detailed comparison:

Category Java JavaScript
Type Object-oriented, class-based, statically typed Multi-paradigm, dynamically typed
Execution Runs on JVM Runs in browsers and Node.js
Use Cases Backend apps, Android apps, enterprise systems Web development (frontend + backend), APIs, interactive UI
Compilation Compiled to bytecode Interpreted/JIT-compiled
Concurrency Multithreading Event loop + async/await
Learning Curve More complex, strict syntax Beginner-friendly, flexible syntax

5. How will you access an HTML code in JavaScript?

There are various methods to access an HTML code in JavaScript. Here are some of the most common methods I would use:

  • Document.getElementById(): Retrieves an element using its unique ID.
const title = document.getElementById("mainTitle");
  • document.getElementsByClassName(): Returns all elements with a specific class name.
const items = document.getElementsByClassName("list-item");
  • document.getElementsByTagName(): Selects elements by their tag name.
const paragraphs = document.getElementsByTagName("p");
  • document.querySelector(): Returns the first matching element based on a CSS selector.
const firstButton = document.querySelector(".btn-primary");
  • document.querySelectorAll(): Returns all matching elements based on a CSS selector.
const allButtons = document.querySelectorAll("button");

6. How many data types are there in JavaScript?

JavaScript has a total of 8 data types, categorized into the following two categories:

  • Primitive Data Types
Data Type Description Example
String Represents textual data "hello"
Number Represents integers and floating-point numbers 10, 3.14
BigInt Represents very large integers beyond Number limits 9007199254740991n
Boolean Represents logical values true, false
Undefined A declared variable with no assigned value let x; // undefined
Null Intentional absence of value let data = null
Symbol Unique and immutable value, used as object keys Symbol("id")
  • Non-Primitive Data Type
Data Type Description Examples
Object Represents collections of key-value pairs and complex data structures. Includes plain objects, arrays, functions, dates, and more. { name: "John" }, [1, 2, 3], function() {}, new Date()

Also Read: JavaScript Cheat Sheet

7. What do you understand about Hoisting in JavaScript?

Hoisting is an interesting mechanism in JavaScript. It allows variable and function declarations to move to the top of their containing scope during the compilation phase. This is all done before the code execution. Developers use variables and call functions before their actual declaration in the code. Here is an example of Hoisting:

greet();  // Output: "Hello"

function greet() {
  console.log("Hello");
}


8. What is Implicit Type Coercion in JavaScript?

Implicit type coercion is the automatic conversion of values from one data type to another. It is done by the JavaScript engine during operations, comparisons, or assignments. This happens without any explicit instruction from the developer to perform the conversion.

9. What do you understand about the DOM in JavaScript?

The Document Object Model, or DOM, is a programming interface used for web documents. Think of it as a bridge between the static web page and the dynamic capabilities of JavaScript. It allows developers to create interactive and responsive user experiences. It describes the structure of an HTML or XML document as a tree of objects. In this structure, each object corresponds to a part of the document, such as elements, attributes, and text.


10. List the keywords and their use in JavaScript.

Here is a comprehensive list of JavaScript keywords and their uses:

Keyword Use / Description
var Declares a variable (function-scoped, hoisted).
let Declares a block-scoped variable.
const Declares a block-scoped constant (cannot be reassigned).
if Executes code based on a condition.
else Executes alternative code if if condition is false.
switch Selects code to run based on matching cases.
case A block inside a switch statement.
default Code that runs if no switch case matches.
for Creates a loop with an initializer, condition, and increment.
while Creates a loop that runs while a condition is true.
do Used with while to run the loop at least once.
break Exits a loop or switch block.
continue Skips one iteration of a loop.
function Declares a function.
return Returns a value from a function.
try Wraps code that may throw an error.
catch Handles errors thrown inside try.
finally Runs code after try/catch (always executes).
throw Throws a custom error.
class Declares a class.
extends Creates a class that inherits from another.
super Calls the parent class constructor/method.
import Imports modules.
export Exports modules.
new Creates a new instance of an object/class.
delete Removes a property from an object.
typeof Returns the type of a variable.
instanceof Checks if an object belongs to a specific class.
in Checks if a property is available in the object.
this Refers to the current object context.
await Pauses execution inside async functions until a promise resolves.
async Declares a function that returns a promise.
yield Pauses and resumes generator functions.
with Extends scope (not recommended; deprecated).
void Evaluates an expression and returns undefined.

Want to Learn Everything About JavaScript?

Boost your coding skills and gain hands-on knowledge in JavaScript.

Explore Now

JavaScript Interview Questions and Answers for Freshers

1. What are the features of the JavaScript programming language?

This programming language provides various features, including:

Feature Description
Closures Functions that access variables from their parent scope even after execution.
Prototypal Inheritance Objects inherit properties and methods from other objects via prototype.
Higher-Order Functions Functions that take other functions as arguments or return them.
Async/Await Modern syntax for handling asynchronous operations in a cleaner way.
Promises Efficiently manage async operations without deep callback nesting.
Event Loop Handles non-blocking operations using queues and scheduling.
ES6 Modules Supports code modularity using import and export.
Arrow Functions Compact function syntax with lexical this binding.
Destructuring Extracts values from arrays/objects into variables easily.
Spread/Rest Operators Copy, merge, and pass multiple data elements flexibly.
Generators Functions that pause and resume execution using yield.
Iterators Custom iteration mechanisms over collections.
WeakMap / WeakSet Stores objects without blocking garbage collection.
Proxy Intercepts operations (get, set, delete) for controlled behavior.
Reflect API Provides meta-programming utilities for object operations.
Typed Arrays Work with raw binary data for high-performance applications.
Symbols Unique identifiers useful for keys and avoiding conflicts.
BigInt Handles extremely large integers beyond Number limits.
Web Workers Enables parallel execution for CPU-heavy tasks.
WebSockets Real-time two-way communication between client and server.

2. What is destructuring in JavaScript, and how can you use it to swap the values of two variables?

Destructuring is a feature that allows you to unpack values from arrays or properties from objects into distinct variables. It makes assignments concise and readable. To swap two variables using array destructuring:

let a = 1;
let b = 2;

// Swapping values
[a, b] = [b, a];

console.log(a); // 2
console.log(b); // 1

3. What are template literals, and how do they improve string handling in JavaScript? Provide an example.

Template literals are string literals enclosed by backticks (`) that support embedded expressions and multi-line strings. This makes string interpolation and formatting easier. Example:

const name = "Alice";

const greeting = `Hello, ${name}! Welcome to the interview.`;

console.log(greeting);

4. How can destructuring be used with function parameters? Give an example using an object parameter with default values.

Destructuring can be applied directly in function parameters to extract values from objects or arrays, and you can assign default values to parameters. Example:

function createUser({ name = "Anonymous", age = 0 } = {}) {
    return `Name: ${name}, Age: ${age}`;
}

// Usage examples
console.log(createUser({ name: "Bob" }));   // "Name: Bob, Age: 0"
console.log(createUser());                  // "Name: Anonymous, Age: 0"

5. What are the different ways to create arrays in JavaScript?

JavaScript provides several ways to create arrays:

Array literal: const arr = [1, 2, 3];
Array constructor: const arr = new Array(1, 2, 3);
Array.of(): const arr = Array.of(1, 2, 3);
Array.from(): const arr = Array.from('hello'); // ['h', 'e', 'l', 'l', 'o']

Each approach has its use cases. The array literal is most common; Array.from and Array.of are often used for array-like or iterable conversions.

6. List and describe the main array types used in JavaScript.

JavaScript supports several array-like types:

Regular Array: The standard, most-used array for storing ordered collections of values.

const arr = [10, 20, 30];

Typed Arrays: Arrays for handling binary data, such as Int8Array, Uint8Array, Float32Array, Float64Array, and (in ES2025) Float16Array.

Example:

const intArr = new Int8Array([1, 2, 3]);

Array-like Objects: Objects with indexed properties and a length, such as arguments and NodeList. Example:

function foo() { console.log(arguments); }

Sparse Arrays: Arrays with missing indices, e.g.,

const arr = [];
arr[5] = 'a'; // arr has empty slots

Typed arrays are used for performance and binary data; regular arrays are used for most general purposes.

7. What is the difference between the map(), filter(), and reduce() array methods? Provide a simple example of each.

map(): Transforms each element in an array and returns a new array.

const nums = [1, 2, 3];
const doubled = nums.map(n => n * 2); // [2, 4, 6]

filter(): Returns a new array containing only elements that pass a test.

const nums = [1, 2, 3, 4];
const evens = nums.filter(n => n % 2 === 0); // [2, 4]

reduce(): Reduces the array to a single value by applying a function cumulatively.

const nums = [1, 2, 3, 4];
const sum = nums.reduce((acc, n) => acc + n, 0); // 10

8. Which array methods mutate the original array, and which do not? Why is this distinction important?

Mutating methods (change the original array):

  • push, pop, shift, unshift, splice, sort, reverse, fill, copyWithin

Non-mutating methods (return a new array or value):

  • map, filter, slice, concat, reduce, find, includes, every, some

This distinction is important because mutating methods can lead to unexpected side effects, especially when sharing arrays across parts of an application. Non-mutating methods help maintain predictable, functional code.

9. How can you iterate over an array in JavaScript? List at least three techniques and when you might prefer each.

for loop: Use when you need full control over the index or want to break early.

for (let i = 0; i < arr.length; i++) {
   // access arr[i]
}

forEach(): Use for side effects on each element; cannot break or return a value.

arr.forEach(item => {
   // perform side effects
});

for…of loop: Use for simple iteration over array values, especially with ES6 or later.

for (const item of arr) {
   // directly access item
}

map/filter/reduce: Use when you want to transform, filter, or accumulate results from an array.

const transformed = arr.map(x => x * 2);
const filtered = arr.filter(x => x > 5);
const reduced = arr.reduce((sum, x) => sum + x, 0);

10. Why do many companies use TypeScript instead of JavaScript?

TypeScript adds static typing, IDE autocompletion, compile-time error checking, and better maintainability for large codebases while still compiling to JavaScript.

JavaScript Interview Questions and Answers for Intermediates

1. What do you understand about undeclared and undefined variables?

  • Undeclared Variable: It is a variable that has never been created or declared with var, let, or const. It always results in a ReferenceError whenever it is used.
  • Undefined Variable: It is a variable that has been declared but not yet assigned a value. It always returns the value undefined when accessed.

The key difference is that an undeclared variable doesn't exist, while an undefined variable exists but has no value.

2. What are global variables in JavaScript?

Global variables are variables that are declared in the global scope. This means they can be accessed from anywhere in the script, from inside functions and loops to conditional blocks, or other parts of the code. They are typically declared outside of any function or block, making them available throughout the entire JavaScript program.

However, using too many global variables is not recommended because they can create naming conflicts and make debugging harder. Here is an example showing how the global variable message is accessible both inside and outside the function.

// Global variable
let message = "Hello, I am a global variable!";

function showMessage() {
  console.log(message); // Accessible inside a function
}

showMessage();

console.log(message); // Accessible outside the function as well

This example shows how the global variable message is accessible both inside and outside the function.

3. Where is the ‘this’ Keyword used in JavaScript?

The keyword ‘this’ in JavaScript is a dynamic reference to the object that is executing the current function or method. Its value is determined at runtime, based on how the function is called. Here is a table showing different function-calling types and how each one determines the value of this keyword.

Function Calling Type How Function Is Called Value of this Example Use Case
Global Function Call Called normally (e.g., func() ) window (browser) or global (Node.js) Default binding
Method Call Called as a property of an object (obj.func()) The object before the dot Object methods
Constructor Call Using new (e.g., new Person()) The newly created object Creating objects
call() / apply() Binding Using func.call(obj) or func.apply(obj) Manually sets this to the provided object Explicit binding
bind() Binding Using func.bind(obj) Permanently binds this to the provided object Function copying
Arrow Function Call Called with (), but arrow functions ignore call context Inherited from the surrounding (lexical) scope Closures, callbacks
Event Handler Call Attached to DOM event (element.onclick = fn) The element that triggered the event DOM programming

4. How do timers work in JavaScript?

Timers are used to set intervals between tasks. These are not a part of the JS engine itself. They come from the Web APIs (browser) or Node.js environment. Here are some of the timers, with examples, used in JavaScript:

1. setTimeout() – run function after delay

setTimeout(() => {
  console.log("Runs after 2 seconds");
}, 2000);

2. setInterval() – run repeatedly

let count = 0;

const timer = setInterval(() => {
  count++;
  console.log("Count:", count);

  if (count === 5) {
    clearInterval(timer); // stop interval
  }
}, 1000);

3. clearTimeout() – cancel a timeout

const id = setTimeout(() => {
  console.log("This will not run");
}, 3000);

clearTimeout(id);

4. clearInterval() – stop repeated task

const intervalId = setInterval(() => {
  console.log("Ping");
}, 500);

setTimeout(() => {
  clearInterval(intervalId);
  console.log("Stopped");
}, 3000);

5. setImmediate() – Node.js example

setImmediate(() => {
  console.log("Runs after current event loop");
});

6. process.nextTick() – Node.js microtask style

console.log("Start");

process.nextTick(() => {
  console.log("Next Tick");
});

console.log("End");

5. What are the different ways to store data in the browser using JavaScript?

JavaScript provides four main browser storage mechanisms, each suited for different use cases:

Storage Type Capacity Lifetime Accessible From Best For
localStorage ~5–10 MB Until manually cleared Same origin, all tabs User preferences, theme, tokens
sessionStorage ~5 MB Tab close / session end Same tab only Temporary form data, wizard steps
Cookies ~4 KB Set via expires/max-age Client + server (via HTTP headers) Auth tokens, tracking, server-read data
IndexedDB Hundreds of MB Until manually cleared Same origin Large structured data, offline apps

Quick example — using localStorage:

// Set
localStorage.setItem("theme", "dark");

// Get
const theme = localStorage.getItem("theme"); // "dark"

// Remove
localStorage.removeItem("theme");

// Clear all
localStorage.clear();

6. What do you understand by a higher-order function in JavaScript?

A higher-order function is a fundamental concept in functional programming and are widely used in JavaScript to promote code reusability, abstraction, and modularity. It either takes one or more functions as arguments or returns a function as its result. This enable powerful patterns like function composition and helps in writing cleaner, more maintainable code.

  • Example 1: When taking one or more functions as arguments.
 function operateOnNumbers(numbers, operation) {
     const result = [];
     for (const num of numbers) {
       result.push(operation(num));
     }
     return result;
   }

   const double = (num) => num * 2;
   const squared = (num) => num * num;

   const numbers = [1, 2, 3];
   const doubledNumbers = operateOnNumbers(numbers, double); // [2, 4, 6]
   const squaredNumbers = operateOnNumbers(numbers, squared); // [1, 4, 9]
  • Example 2: When returns a function as its result.
  function createMultiplier(factor) {
     return function (number) {
       return number * factor;
     };
   }

   const multiplyByTwo = createMultiplier(2);
   const multiplyByFive = createMultiplier(5);

   console.log(multiplyByTwo(10)); // 20
   console.log(multiplyByFive(10)); // 50

7. How to read and write files in JavaScript?

The process of reading and writing files in JavaScript depends on the environment in which the JavaScript code is executed. Here are the most common ways and environments a developer will be working on:

1. Reading & Writing Files in Browser JavaScript

  • Browsers do not allow direct disk access for security reasons.
  • But you can read files using FileReader, and write/save files using Blob + download link.

Example 1: Read a File in Browser (FileReader API)

HTML:

<input type="file" id="fileInput">

JavaScript:

const input = document.getElementById("fileInput");

input.addEventListener("change", function() {
  const file = input.files[0];
  const reader = new FileReader();

  reader.onload = function(event) {
    console.log("File content:");
    console.log(event.target.result);
  };

  reader.readAsText(file);
});

Example 2: Write (Download) a File in Browser

function saveFile() {
  const data = "Hello, this is file content!";
  const blob = new Blob([data], { type: "text/plain" });
  const url = URL.createObjectURL(blob);

  const link = document.createElement("a");
  link.href = url;
  link.download = "example.txt";
  link.click();

  URL.revokeObjectURL(url);
}

saveFile();

2. Reading & Writing Files in Node.js

Node.js allows full file system access using the built-in fs (File System) module.

Example 1: Read File (Synchronous)

const fs = require("fs");

const data = fs.readFileSync("example.txt", "utf8");
console.log(data);

Example 2: Read File (Asynchronous)

const fs = require("fs");

fs.readFile("example.txt", "utf8", (err, data) => {
  if (err) throw err;
  console.log(data);
});

8. What do you understand about modules in JavaScript?

JavaScript modules are the best way to partition the code into smaller and reusable blocks. They help to move functions, variables, and objects from one file to another. This helps to organize code and reduce global namespace pollution to nearly zero. They have an in-built support in modern JavaScript using import and export statements.

9. How are client-side and server-side JavaScript different?

Client-side JavaScript runs in the browser and is mainly used for updating the UI, handling events, and interacting with the DOM. Server-side JavaScript runs on the server (Node.js) and is used for database operations, authentication, file handling, and backend logic. Client-side code is visible to users, while server-side code remains hidden and secure on the server. Here are some of the differences between them:

Feature Client-Side JS Server-Side JS
Runs In Browser Node.js server
Main Use UI, DOM, events Database, APIs, backend
Security Visible to the user Hidden and secure
File System Access No Yes
Database Access No Yes

10. What is the prototype design pattern?

The Prototype design pattern is basically a creational pattern that creates new objects by cloning an existing object. This way, you do not have to initiate them from scratch. This method is mostly useful for the prototype-based nature of JavaScript. This is the best method to create objects in resource-intensive conditions or when they need to inherit properties.

The Prototype Pattern builds various objects, but does not return uninitialized objects. Its objects always have the values of a template or sample object. Here is an example of prototyping:

// The Prototype object
const carPrototype = {
  wheels: 4,
  engine: 'V6',
  drive: function() {
    console.log('Driving the car.');
  },
  stop: function() {
    console.log('Stopping the car.');
  }
};

// Creating a new car object by cloning the prototype
const myCar = Object.create(carPrototype);
myCar.color = 'red'; // Customizing the cloned object

const anotherCar = Object.create(carPrototype);
anotherCar.color = 'blue';

myCar.drive(); // Output: Driving the car.
console.log(anotherCar.wheels); // Output: 4

Here, carPrototype acts as the prototype. New car objects (myCar, anotherCar) are created by cloning carPrototype using Object.create(), inheriting its properties and methods. These cloned objects can also be further customized.

Also Explore: JavaScript MCQs

JavaScript Coding Interview Questions and Answers

1. Write a JavaScript code for adding new elements dynamically.

const btn = document.getElementById("add");
const list = document.getElementById("items");

btn.addEventListener("click", () => {
  const li = document.createElement("li");
  li.textContent = "New Item";
  list.appendChild(li);
});

2. Write a JavaScript code to remove an element when a button is clicked.

document.getElementById("remove").onclick = () => {
  const item = document.getElementById("box");
  item.remove();
};

3. Write a JavaScript program to swap two numbers without using a third variable.

let a = 5, b = 10;
[a, b] = [b, a];
console.log(a, b); // 10 5

4. Write a JavaScript program to find the largest number in an array.

function largest(arr) {
  return Math.max(...arr);
}

console.log(largest([3, 9, 2, 7])); // 9

5. Write JavaScript code to check if a string is a palindrome.

function isPalindrome(str) {
  return str === str.split("").reverse().join("");
}

console.log(isPalindrome("madam")); // true

6. Write JavaScript code to count how many times each character appears in a string.

function charCount(str) {
  const map = {};
  for (const ch of str) {
    map[ch] = (map[ch] || 0) + 1;
  }
  return map;
}

console.log(charCount("hello"));

7. Write JavaScript code to reverse a number.

function reverseNumber(num) {
  return Number(String(num).split("").reverse().join(""));
}

console.log(reverseNumber(12345)); // 54321

8. Write a JavaScript program to generate a random number between 1 and 100.

function randomNum() {
  return Math.floor(Math.random() * 100) + 1;
}

console.log(randomNum());

9. Write JavaScript code to remove duplicate values from an array.

function removeDuplicates(arr) {
  return [...new Set(arr)];
}

console.log(removeDuplicates([1,2,2,3,4,4]));

10. Write a JavaScript program to sort an array without using sort().

function bubbleSort(arr) {
  for (let i = 0; i < arr.length; i++) {
    for (let j = 0; j < arr.length - i - 1; j++) {
      if (arr[j] > arr[j + 1]) {
        [arr[j], arr[j + 1]] = [arr[j + 1], arr[j]];
      }
    }
  }
  return arr;
}

console.log(bubbleSort([4,2,7,1]));

JavaScript Technical Interview Questions and Answers

Here are some of the most asked technical JavaScript interview questions and answers usually asked in the interview.

1. What is the difference between synchronous and asynchronous programming in JavaScript?

Synchronous programming executes code line by line, where each operation waits for the previous one to finish. Asynchronous programming allows tasks like API calls, timers, and file operations to run in the background without blocking the main thread. JavaScript uses callbacks, Promises, and async/await to handle asynchronous operations efficiently.

2. What is event delegation in JavaScript?

Event delegation is a technique where a parent element handles events for its child elements using event bubbling. Instead of attaching listeners to multiple child elements, a single listener is attached to the parent, improving performance and reducing memory usage.

document.getElementById("list").addEventListener("click", function(e) { if (e.target.tagName === "LI") { console.log(e.target.textContent); } });

3. What is the difference between call(), apply(), and bind()?

All three methods are used to control the value of the this keyword in JavaScript.

  • call() invokes a function immediately and accepts arguments individually.
  • apply() invokes a function immediately but accepts arguments as an array.
  • bind() returns a new function with a permanently bound this value.

4. What are closures in JavaScript?

A closure is created when a function remembers variables from its outer scope even after the outer function has finished execution. Closures are commonly used for data privacy, function factories, and maintaining state.

function counter() { let count = 0;

return function() {
count++;
return count;
};
}

const increment = counter();

console.log(increment()); // 1
console.log(increment()); // 2

5. What is debouncing in JavaScript?

Debouncing is a performance optimization technique that limits how often a function executes. The function only runs after a specified delay once the user stops triggering the event. It is commonly used in search bars, resize events, and autocomplete features.

6. What is throttling in JavaScript?

Throttling ensures a function executes at a fixed interval, regardless of how many times the event occurs. It is useful for scroll events, mouse movement tracking, and rate-limiting actions.

7. What is the difference between localStorage and sessionStorage?

Both are Web Storage APIs used to store data in the browser.

Feature localStorage sessionStorage
Lifetime Persists until manually cleared Cleared when tab/browser closes
Scope Shared across tabs Limited to one tab/session
Storage Limit ~5-10 MB ~5 MB

8. What is currying in JavaScript?

Currying is a functional programming technique where a function with multiple arguments is transformed into a sequence of functions, each taking one argument at a time.

function multiply(a) { return function(b) { return a * b; }; }

console.log(multiply(2)(5)); // 10

9. What is optional chaining in JavaScript?

Optional chaining (?.) allows safe access to deeply nested object properties without throwing errors if a property is undefined or null.

const user = { profile: { name: "John" } };

console.log(user.profile?.name); // John
console.log(user.address?.city); // undefined

10. What is the difference between shallow copy and deep copy in JavaScript?

A shallow copy copies only the first level of an object, while nested objects still reference the original memory location. A deep copy creates completely independent copies of all nested objects.

Type Behavior Example
Shallow Copy Nested objects are shared Object.assign(), spread operator
Deep Copy Completely independent copy structuredClone(), JSON methods

JavaScript Interview Questions and Answers for 3+ Year Experience Professionals

1. What is the event loop in JavaScript and why is it needed?

JavaScript is single-threaded, but it handles asynchronous tasks through the event loop. The event loop continuously checks whether the call stack is empty and then pushes pending callbacks (tasks/microtasks) into the stack. This enables asynchronous behavior without blocking execution.

2. What’s the difference between Microtask Queue and Macrotask Queue?

Microtasks (Promises, MutationObservers) run before macrotasks (setTimeout, setInterval). After each script execution, the engine will empty all microtasks before moving to the next macrotask.

3. Why is async/await preferred over callbacks?

Callbacks cause "callback hell" — deeply nested, hard-to-read code. Promises improved this with chaining, and async/await makes asynchronous code read like synchronous code while still being non-blocking. Error handling with try/catch is also far cleaner than nested .catch() calls.

// Callback hell
getData(function(a) {
  getMore(a, function(b) {
    getEvenMore(b, function(c) {
      console.log(c); // deeply nested
    });
  });
});

// async/await — same logic, readable
async function run() {
  const a = await getData();
  const b = await getMore(a);
  const c = await getEvenMore(b);
  console.log(c);
}

4. What are the three states of a Promise?

A Promise has three states:

  • Pending — initial state, operation not yet completed.
  • Fulfilled — operation completed successfully, .then() runs.
  • Rejected — operation failed, .catch() runs.

Once a Promise moves from Pending to either Fulfilled or Rejected, it is immutable — its state cannot change again.

const p = new Promise((resolve, reject) => {
  setTimeout(() => resolve("done!"), 1000);
});

p.then(val => console.log(val))   // "done!"
 .catch(err => console.error(err))
 .finally(() => console.log("always runs"));

4a. What is the difference between Promise.all(), Promise.allSettled(), Promise.race(), and Promise.any()?

These four methods handle multiple Promises differently and are commonly asked in intermediate-to-senior interviews:

Method Resolves when Rejects when Use case
Promise.all() All promises fulfill Any one rejects Run parallel tasks where all must succeed
Promise.allSettled() All promises settle (either way) Never rejects Run all and inspect each result individually
Promise.race() First promise settles First promise rejects Timeout patterns, first-response wins
Promise.any() First promise fulfills All promises reject Fallback strategies, first success wins
const p1 = fetch("/api/users");
const p2 = fetch("/api/orders");

// All must succeed
const [users, orders] = await Promise.all([p1, p2]);

// Don't care if some fail
const results = await Promise.allSettled([p1, p2]);
results.forEach(r => {
  if (r.status === "fulfilled") console.log(r.value);
  else console.error(r.reason);
});

5. What are Generators in JavaScript?

Generators are special functions defined with function* that can pause execution using yield and resume later. They support lazy evaluation and stateful iteration.

6. What is an iterator in JavaScript?

An iterator is an object that follows the iterator protocol and provides a next() method returning { value, done }, enabling sequential data access (like for...of loops).

7. Why are ES modules preferred over CommonJS?

ES modules (import/export) support compile-time optimization (tree shaking), are asynchronous, and work natively in browsers, unlike CommonJS which is synchronous and Node-specific.

8. What causes memory leaks in JavaScript?

Memory leaks often occur due to abandoned DOM references, global variables, unreleased timers, or event listeners that prevent objects from being garbage collected.

9. How do you improve JavaScript performance?

Minimizing DOM manipulation, using debouncing/throttling, avoiding deep nested loops, lazy loading assets, and caching results all improve performance.

10. How does the Node.js event loop differ from the browser’s?

Node.js has multiple execution phases (timers → pending → poll → check → close) while browsers treat tasks and microtasks more simply. Node’s loop also interacts with its C++ bindings.

JavaScript Interview Questions for 5+ Year Experience Professionals

1. What are async iterators?

Async iterators allow iterating over asynchronous data using for await ... of, making streaming operations simpler and cleaner.

2. What is tree shaking?

Tree shaking is a dead code elimination technique used by bundlers like Webpack and Rollup. It statically analyzes your import/export statements at build time and removes any exported code that is never imported anywhere — resulting in a smaller bundle size.

It only works with ES modules (import/export), not CommonJS (require), because CommonJS imports are dynamic and cannot be analyzed statically.

// utils.js
export function usedFunction() { return "I am used"; }
export function unusedFunction() { return "I am never imported"; }

// main.js
import { usedFunction } from "./utils.js";
// unusedFunction is tree-shaken out of the final bundle

To enable tree shaking: set "sideEffects": false in your package.json and use ES module syntax throughout your codebase.

3. What is a Proxy in JavaScript?

A Proxy wraps an object and intercepts fundamental operations (get, set, delete, etc.), enabling behavior like validation, logging, or custom access logic.

4. Why use WeakMap instead of Map?

The key difference is memory management. In a regular Map, object keys are held with a strong reference — the garbage collector cannot remove them even if no other part of your code references them. In a WeakMap, keys are held with a weak reference, so when the object key has no other references, it is automatically garbage collected.

Feature Map WeakMap
Key typesAny valueObjects only
Garbage collectionPrevents GC of keysAllows GC of keys
IterableYesNo
Size propertyYesNo
Best forGeneral key-value storageStoring metadata about DOM nodes / objects without leaking memory
// Common use case: caching computed data tied to DOM nodes
const cache = new WeakMap();

function getMetadata(element) {
  if (!cache.has(element)) {
    cache.set(element, { clicks: 0 });
  }
  return cache.get(element);
}

// When the element is removed from DOM and dereferenced,
// WeakMap automatically releases the cached data — no memory leak.

5. Why does typeof null === 'object'?

It’s a historical bug from the first JS implementation where null’s type tag referenced “object.” Changing it now would break legacy code.

6. What is a polyfill in JavaScript?

A polyfill is a piece of JavaScript code that replicates the behavior of a modern browser API or language feature in older environments that do not support it natively. The term comes from a UK brand of wall filler — it fills in the gaps.

For example, Array.prototype.includes() does not exist in IE11. A polyfill adds it manually:

// Polyfill for Array.prototype.includes
if (!Array.prototype.includes) {
  Array.prototype.includes = function(searchElement) {
    for (let i = 0; i < this.length; i++) {
      if (this[i] === searchElement) return true;
    }
    return false;
  };
}

// Now works in browsers that don't support it natively
[1, 2, 3].includes(2); // true

Popular polyfill libraries include core-js (used internally by Babel) and Polyfill.io, which serves only the polyfills each browser actually needs.

Polyfill vs Transpiling: A polyfill adds missing runtime functionality. A transpiler (like Babel) converts modern syntax (arrow functions, optional chaining) into older syntax at build time. Both are often used together.

7. What are the main types of errors in JavaScript?

JavaScript errors can be divided into various types based on different scenarios. Understanding these error types helps developers pinpoint debugging problems faster. Below is the list of common JavaScript error types and their meanings.

Error Type Description
SyntaxError Occurs when code has invalid syntax (e.g., missing parentheses or brackets).
ReferenceError Raised when referencing a variable that hasn’t been declared.
TypeError Happens when a value is not of the expected type (e.g., calling a non-function as a function).
RangeError Thrown when a value is not within the allowed range (e.g., invalid array length).
EvalError Related to the use of the eval() function (rare in modern code).
URIError Occurs with malformed URI handling functions (e.g., decodeURIComponent).

8. How do you handle exceptions in JavaScript? Explain with an example.

JavaScript provides the try...catch...finally construct for handling exceptions. The try block wraps code that might throw an error, catch block runs if an error occurs, and finally block executes always for cleanup.


try {
    // Code that may throw an error
    throw new Error("Something went wrong!");
} 
catch (err) {
    console.error("Caught error:", err.message);
} 
finally {
    console.log("This always runs");
}

This structure prevents application crashes and helps handle problems gracefully.

9. What is the purpose of the throw statement in JavaScript error handling?

The throw statement allows developers to create custom error messages and stop code execution immediately. It helps communicate issues clearly and allows handling logic to occur.


function divide(a, b) {
    if (b === 0) {
        throw new Error("Division by zero is not allowed");
    }
    return a / b;
}

10. How can you debug JavaScript code effectively?

  • Using console.log() and console.error() to track values and flow.
  • Using browser developer tools (Chrome DevTools) for stepping through code.
  • Setting breakpoints and conditional breakpoints.
  • Inspecting network calls, event listeners, and performance using DevTools panels.

These techniques help identify issues efficiently and enhance code reliability.

Advanced JavaScript Interview Questions and Answers

Now we will delve into the most asked JavaScript interview questions and answers for experienced professionals. These questions are asked to check candidates' proficiency in the most advanced concepts.

1. What is memoization in JavaScript?

Memoization is an optimization technique. It stores the results of expensive function calls and also returns the cached result when the same inputs occur again. This technique significantly improves performance, especially for functions that are frequently called with the same arguments or involve complex computations. Let’s understand it with an example:

function memoize(fn) {
  const cache = {};

  return function (...args) {
    const key = JSON.stringify(args);

    // Return cached result if available
    if (cache[key]) {
      console.log("Returning from cache:", cache[key]);
      return cache[key];
    }

    // Compute and store in cache
    const result = fn(...args);
    cache[key] = result;
    console.log("Computed result:", result);
    return result;
  };
}

// Expensive function example (recursive fibonacci)
function slowFibonacci(n) {
  if (n <= 1) return n;
  return slowFibonacci(n - 1) + slowFibonacci(n - 2);
}

// Memoized version
const fastFibonacci = memoize(slowFibonacci);

console.log(fastFibonacci(10)); // Computed fi

What it does:

Line Meaning
const cache = {}; Creates an empty object to store previously calculated results.
(...args) Allows the function to receive any number of arguments.
JSON.stringify(args) Converts inputs into a unique string key for caching.
if (cache[key]) ... Checks if the result for these inputs already exists.
fn(...args) Calls the original function only if the result is not in cache.
cache[key] = result Stores the computed value in the cache.
return result; Returns the final value.

2. How would you detect the operating system on the client machine?

It is an easy process. You just have to use navigator.userAgent property or navigator.appVersion. It is a read-only property that returns the string representing the version information of the browser being used.

3. What do you know about variable typing in JavaScript?

The data type is not explicitly declared in JavaScript. This means you can also change it during runtime. Here is an example of variable typing:

Guru = 42;
Guru = "igmGuru";

4. Explain generator functions in JavaScript.

Generator functions are a kind of function that can be paused and resumed during execution. This functionality allows them to yield multiple values over time rather than returning a single value and terminating. They are defined using the function* syntax. Here is an example:

function* numberGenerator() {
  yield 1;
  yield 2;
  yield 3;
}

const gen = numberGenerator();

console.log(gen.next()); // { value: 1, done: false }
console.log(gen.next()); // { value: 2, done: false }
console.log(gen.next()); // { value: 3, done: false }
console.log(gen.next()); // { value: undefined, done: true }

5. What is WeakSet in JavaScript?

A WeakSet is a collection of unique objects, just like a regular Set, but with a crucial difference. It stores ‘weak’ references to its elements. This means that if an object stored in a WeakSet is no longer referenced anywhere else in the code, it can be garbage collected, even if it's still present in the WeakSet. Let’s see an example:

let weakSet = new WeakSet();

let obj1 = { name: "John" };
let obj2 = { age: 25 };

weakSet.add(obj1);
weakSet.add(obj2);

console.log(weakSet.has(obj1)); // true

// Remove reference to obj1
obj1 = null;

// Now obj1 becomes eligible for garbage collection
// weakSet will automatically remove it

6. How many methods are there to make an object?

There are multiple techniques to create objects. Here are some of the most commonly used ones:

1. Object Literal

const obj = { name: "John", age: 25 };

2. Using the Object Constructor

const obj = new Object();
obj.name = "John";
obj.age = 25;

3. Constructor Function

function Person(name, age) {
  this.name = name;
  this.age = age;
}

const p1 = new Person("John", 25);

4. ES6 Class

class Person {
  constructor(name, age) {
    this.name = name;
    this.age = age;
  }
}

const p2 = new Person("John", 25);

5. Object.create()

const proto = { greet() { console.log("Hello"); } };
const obj = Object.create(proto);
obj.name = "John";

6. Factory Function

function createPerson(name, age) {
  return { name, age };
}

const p3 = createPerson("John", 25);

7. Using JSON

const obj = JSON.parse('{"name": "John", "age": 25}');

8. Using Object.assign()

const obj = Object.assign({}, { name: "John", age: 25 });

9. Using a Singleton Pattern

const obj = new function() {
  this.name = "John";
  this.age = 25;
};

7. What are the rest parameter and the spread operator?

These are newly introduced features of JavaScript ES6. Both of them use a similar syntax (...), but for different uses. The spread operators are used for spreading elements from an object or array. The rest parameter is used for collecting multiple values into an array. Let’s see examples of their uses:

  • Spread Operator Example: The spread operator is mostly used to copy, combine, and expand arrays or objects.
const arr1 = [1, 2, 3];
const arr2 = [4, 5, 6];

// Combining arrays using spread
const combined = [...arr1, ...arr2];
console.log(combined); // Output: [1, 2, 3, 4, 5, 6]
  • Rest Parameter Example: The rest parameter is used to gather multiple arguments into a single array.
function sum(...numbers) {
  return numbers.reduce((total, num) => total + num, 0);
}

console.log(sum(10, 20, 30)); // Output: 60

8. What is closure in JavaScript?

Closure is a combination of a function and the lexical environment within which that function was declared. This allows an inner function to access the variables and scope of its outer function, even after the outer function has finished executing. Here is an example of closure in JavaScript:

function createCounter() {
  let count = 0; // 'count' is a variable in the outer function's scope

  function increment() {
    count++;
    console.log(count);
  }

  return increment; // The inner function 'increment' is returned
}

const myCounter = createCounter(); // 'myCounter' now holds the 'increment' function

myCounter(); // Output: 1 (accesses and modifies 'count' from the closure)
myCounter(); // Output: 2 (accesses and modifies 'count' from the closure)

9. What do you understand by event delegation in JavaScript?

Event delegation is a special technique that os used to manage evens for multiple child events by a single event listener on a parent element. It uses the process of event bubbling. This reduces the number of listeners, simplifies code by centralizing logic, and makes it easier to handle events on dynamically added elements. This all results in beter performance.

10. Explain Immediately Invoked Function Expression (IIFE).

An Immediately Invoked Function Expression (IIFE) in JavaScript is a function that is defined and executed immediately after its creation. It is a common pattern used to create a private scope for variables, preventing them from polluting the global scope. Here is the basic syntax of IIFE:

(function() {
  // Code to be executed immediately
})();

Example of using IIFE:

(function() {
  let message = "Hello from IIFE!";
  console.log(message);
})();

Output:

Hello from IIFE!

Related Article: Top Frontend Programming Languages

11. How do you handle errors in asynchronous JavaScript code (Promises, async/await)?

For promises, errors are caught using the .catch() method:


fetch('https://api.example.com/data')
    .then(response => response.json())
    .catch(error => {
        console.error('Error fetching data:', error);
    });

With async/await, try...catch is used to handle errors:


async function fetchData() {
    try {
        const response = await fetch('https://api.example.com/data');
        const data = await response.json();
        return data;
    } 
    catch (error) {
        console.error('Fetch error:', error);
    }
}

This ensures that asynchronous operations fail safely and do not break application flow.

Read Also- Top Python Interview Questions

Scenario-Based JavaScript Questions and Answers

Modern JavaScript interviews are no longer limited to theoretical definitions as companies are now asking scenario-based and debugging questions to evaluate how well you apply concepts in real-world situations. In this section, you will find practical problems that test your understanding of closures, asynchronous behavior, performance optimization, memory management and debugging skills.

1. Why does this loop print 5 five times instead of 0 to 4? Can you debug it?

for (var i = 0; i < 5; i++) { setTimeout(() => { console.log(i); }, 1000); }

Problem: It prints 5 five times.

Reason: Because var is function-scoped. By the time the callback executes, the loop has completed and i becomes 5.

Solution: Use let (block-scoped variable).

for (let i = 0; i < 5; i++) { setTimeout(() => { console.log(i); }, 1000); }

2. API Call Returns Empty Data Sometimes. Tell me what’s Wrong?

function getData() { let result;

fetch("https://api.example.com/data
")
.then(res => res.json())
.then(data => {
result = data;
});

return result;
}

console.log(getData());

Problem: It logs undefined.

Reason: fetch() is asynchronous. The function returns before the promise resolves.

Solution: Use async/await.

async function getData() { const response = await fetch("https://api.example.com/data"); return await response.json(); }

3. The App Slows Down After Navigating Multiple Times. How do you solve it?

Likely Cause: Memory leak due to unremoved event listeners.

function setup() { window.addEventListener("resize", () => { console.log("Resized"); }); }

Fix: Remove listeners when the component/page is destroyed.

function cleanup() { window.removeEventListener("resize", handler); }

4. How do you solve an issue where a dynamically Added Buttons Do Not Trigger Click Event

Reason: The listener was attached before dynamic elements were added.

Solution: Use event delegation.

document.getElementById("parent").addEventListener("click", function(e) { if (e.target.classList.contains("btn")) { console.log("Button clicked"); } });

5. How Would You Optimize Rendering 10,000 DOM Elements?

I would consider follwing these best practices:

  • Use DocumentFragment
  • Batch DOM updates
  • Virtualize list rendering
const fragment = document.createDocumentFragment();

for (let i = 0; i < 10000; i++) {
const div = document.createElement("div");
div.textContent = i;
fragment.appendChild(div);
}

document.body.appendChild(fragment);

6. Why Does typeof null Return “object”?

Answer: It is a historical bug in JavaScript’s early implementation. Changing it would break legacy code, so it remains.

7. User Input Is Injected into innerHTML - What’s the Risk?

div.innerHTML = userInput;

Risk: Cross-Site Scripting (XSS).

Safer Alternative:

div.textContent = userInput;

8. How Would You Debounce a Search Input?

function debounce(fn, delay) { let timeout;

return function (...args) {
clearTimeout(timeout);
timeout = setTimeout(() => {
fn.apply(this, args);
}, delay);
};
}

9. Why Does This Object Lose Its “this” Context?

const user = { name: "John", greet() { setTimeout(function() { console.log(this.name); }, 1000); } };

user.greet();

Problem: This becomes window/global.

Solution: Use an arrow function.

setTimeout(() => { console.log(this.name); }, 1000);

10. How Would You Prevent Multiple Rapid Button Clicks?

Solution: Disable the button temporarily.

button.addEventListener("click", async function() { button.disabled = true; await submitForm(); button.disabled = false; });

Tips to Prepare for a JavaScript Interview

Preparing for a JavaScript interview requires more than memorizing concepts. Interviewers usually evaluate your understanding of core JavaScript fundamentals, problem-solving ability, debugging skills, and practical coding experience. Following these tips can significantly improve your confidence and performance during technical interviews.

  • Master JavaScript Fundamentals: Build a strong understanding of variables, data types, functions, scope, closures, hoisting, prototypes, objects, arrays, and the this keyword.
  • Practice Coding Every Day: Solve JavaScript coding challenges involving arrays, strings, objects, recursion, and algorithms on platforms like LeetCode, HackerRank, or Codewars.
  • Understand Asynchronous JavaScript: Learn callbacks, Promises, async/await, the Event Loop, microtasks, and macrotasks, as these are frequently tested in interviews.
  • Strengthen DOM Knowledge: Practice DOM manipulation, event handling, event delegation, and browser APIs since frontend interviews often include practical DOM-related questions.
  • Be Comfortable with ES6+ Features: Review arrow functions, destructuring, template literals, spread/rest operators, modules, optional chaining, nullish coalescing, and other modern JavaScript features.
  • Learn Debugging Techniques: Become familiar with browser developer tools, breakpoints, console methods, stack traces, and debugging asynchronous code.
  • Build Real Projects: Create projects such as a to-do app, weather application, expense tracker, or quiz application. Practical experience helps you confidently explain your coding decisions during interviews.
  • Revise Common Interview Questions: Practice explaining concepts like closures, event bubbling, event capturing, prototypes, currying, debouncing, throttling, and shallow vs. deep copy without referring to notes.
  • Prepare for Scenario-Based Questions: Many companies ask debugging and optimization questions. Practice reading unfamiliar code, identifying bugs, improving performance, and explaining your thought process.
  • Participate in Mock Interviews: Simulate real interview environments with peers or mentors. Mock interviews help improve communication skills, confidence, and time management while solving coding problems.

A successful JavaScript interview preparation strategy combines theoretical knowledge with hands-on practice. The more real-world applications and coding problems you solve, the easier it becomes to answer both conceptual and scenario-based interview questions with confidence.

Wrapping Up

This JavaScript interview questions and answer guide has all the concepts one should prepare for before going for an interview. By preparing these questions, you will be confident enough to crack any type of interview, whether you go as a beginner or an experienced professional. You can also check our self-paced training programs to get a detailed guide.

FAQs: JavaScript Interview Questions

1. Which JavaScript topics are most commonly asked in interviews?

Based on frequency across technical interviews in 2025, the most commonly asked JavaScript topics are: closures, the event loop, Promises and async/await, prototypal inheritance, scope and hoisting, the this keyword, debouncing and throttling, and array methods (map, filter, reduce). For senior roles, add memory management, design patterns, and performance optimization.

2. How long should I prepare for a JavaScript interview?

For a fresher or junior role, 2–3 weeks of focused preparation covering ES6+ fundamentals, DOM manipulation, and basic async patterns is typically sufficient. For mid-level roles, add 1–2 weeks on closures, prototypes, and system design basics. For senior roles, allow 4–6 weeks and include deep dives into performance, security (XSS, CSRF), and architectural patterns.

3. Is JavaScript enough to get a frontend developer job?

Core JavaScript knowledge is the foundation, but most frontend roles in 2025 also expect familiarity with at least one framework (React, Vue, or Angular), CSS fundamentals, Git, and basic REST API consumption. Pure JavaScript expertise is highly valued, but companies typically expect it alongside these adjacent skills rather than in isolation.

4. What is the difference between JavaScript and TypeScript in interviews?

JavaScript interview questions focus on runtime behavior, how the language executes, scope, closures, and async patterns. TypeScript questions additionally cover static types, interfaces vs types, generics, and utility types like Partial, Pick, and Readonly. Many companies now interview on both, expect a JS fundamentals round followed by TS-specific questions if TypeScript is listed in the job description.

5. How much does a JavaScript developer earn?

According to Glassdoor and AmbitionBox, JavaScript developer salaries vary by experience and location. In India, entry-level developers typically earn ₹3–6 LPA, mid-level ₹8–18 LPA, and senior developers ₹20–40 LPA. In the USA, the average JavaScript developer salary ranges from $75,000 to $130,000+ per year depending on seniority and company size. Salaries at FAANG-level companies can exceed $180,000 total compensation for senior engineers.

About the Author
Sanjay Prajapat
About the Author

Sanjay Prajapat is a Data Engineer and technology writer with expertise in Python, SQL, data visualization, and machine learning. He simplifies complex concepts into engaging content, helping beginners and professionals learn effectively while exploring emerging fields like AI, ML, and cybersecurity in today’s evolving tech landscape.

Drop Us a Query
Fields marked * are mandatory
×

Your Shopping Cart


Your shopping cart is empty.