JavaScript Interview Questions


Beginners To Experts


The site is under development.

JavaScript Interview Questions

// Declaring a variable with var keyword
var x = 10;  // Declare variable x and assign 10

// Declaring a variable with let keyword
let y = 20;  // Declare variable y and assign 20

// Declaring a constant
const z = 30;  // Declare constant z and assign 30

// Printing variables to console
console.log(x);  // Output: 10
console.log(y);  // Output: 20
console.log(z);  // Output: 30
      
10
20
30

// Declaring a function named greet
function greet(name) {
  return "Hello, " + name + "!";  // Return greeting string
}

// Calling the function and storing result
var message = greet("Alice");  // message = "Hello, Alice!"

// Printing the message
console.log(message);  // Output: Hello, Alice!
      
Hello, Alice!

// Creating a JavaScript object
var person = {
  firstName: "John",  // First name property
  lastName: "Doe",    // Last name property
  age: 30,             // Age property
  fullName: function() {  // Method to get full name
    return this.firstName + " " + this.lastName;
  }
};

// Accessing object properties and method
console.log(person.firstName);  // Output: John
console.log(person["lastName"]);  // Output: Doe
console.log(person.fullName());  // Output: John Doe
      
John
Doe
John Doe

// Creating an array
var fruits = ["Apple", "Banana", "Cherry"];  // Array of fruit strings

// Accessing array elements
console.log(fruits[0]);  // Output: Apple
console.log(fruits[1]);  // Output: Banana
console.log(fruits[2]);  // Output: Cherry

// Adding an element to the array
fruits.push("Date");  // Adds 'Date' at the end of array
console.log(fruits);  // Output: ["Apple", "Banana", "Cherry", "Date"]
      
Apple
Banana
Cherry
["Apple", "Banana", "Cherry", "Date"]

// Using var - function scoped
var a = 1;  // Declare a using var
if (true) {
  var a = 2;  // Re-declares a within same function scope
  console.log(a);  // Output: 2
}
console.log(a);  // Output: 2

// Using let - block scoped
let b = 1;  // Declare b using let
if (true) {
  let b = 2;  // Creates new b in block scope
  console.log(b);  // Output: 2
}
console.log(b);  // Output: 1

// Using const - block scoped and immutable
const c = 3;  // Declare constant c
console.log(c);  // Output: 3
      
2
2
1
3

// Different data types in JavaScript
let str = "Hello";  // String type
let num = 100;       // Number type
let bool = true;     // Boolean type
let undef;           // Undefined type
let nul = null;      // Null type
let obj = { key: "value" };  // Object type
let arr = [1, 2, 3];         // Array type

console.log(typeof str);  // Output: string
console.log(typeof num);  // Output: number
console.log(typeof bool);  // Output: boolean
console.log(typeof undef);  // Output: undefined
console.log(typeof nul);  // Output: object (special case)
console.log(typeof obj);  // Output: object
console.log(typeof arr);  // Output: object
      
string
number
boolean
undefined
object
object
object

// == checks for value equality with type coercion
console.log(5 == '5');  // Output: true

// === checks for value and type equality
console.log(5 === '5');  // Output: false

console.log(5 === 5);  // Output: true
      
true
false
true

// Function declaration
function greet(name) {
  return 'Hello, ' + name + '!';
}

console.log(greet('Alice'));  // Output: Hello, Alice!
      
Hello, Alice!

// Object with properties and methods
let person = {
  name: 'John',
  age: 30,
  greet: function() {
    return 'Hi, I am ' + this.name;
  }
};

console.log(person.name);  // Output: John
console.log(person.greet());  // Output: Hi, I am John
      
John
Hi, I am John

// Declaring an array
let fruits = ['apple', 'banana', 'cherry'];

console.log(fruits[0]);  // Output: apple
console.log(fruits.length);  // Output: 3

// Adding a new element
fruits.push('date');
console.log(fruits);  // Output: ['apple', 'banana', 'cherry', 'date']
      
apple
3
apple,banana,cherry,date

// isNaN checks if a value is Not-a-Number
console.log(isNaN(123));     // Output: false
console.log(isNaN('abc'));   // Output: true
console.log(isNaN('123'));   // Output: false
      
false
true
false

// null is a value assigned by the programmer
let a = null;
console.log(a);  // Output: null

// undefined means a variable is declared but not assigned
let b;
console.log(b);  // Output: undefined
      
null
undefined

// Creating an object using literal syntax
let car = {
  brand: 'Toyota',
  model: 'Corolla',
  year: 2021
};

console.log(car.brand);  // Output: Toyota
      
Toyota

// JavaScript events are actions that can be handled with code
// Example: click event
document.getElementById('btn').addEventListener('click', function() {
  alert('Button clicked!');
});
      
(Displays an alert when the button with id "btn" is clicked)

// Event bubbling means the event starts from the target element and bubbles up
// Example: click event on child and parent
document.getElementById('parent').addEventListener('click', function() {
  console.log('Parent clicked');
});

document.getElementById('child').addEventListener('click', function() {
  console.log('Child clicked');
});
      
Clicking #child logs:
Child clicked
Parent clicked

// == compares values after type coercion
console.log(5 == '5');  // Output: true

// === compares both value and type
console.log(5 === '5'); // Output: false
      
true
false

// A JavaScript function is a block of code that performs a task
function greet(name) {
  return "Hello, " + name + "!";
}

console.log(greet("Alice"));  // Output: Hello, Alice!
      
Hello, Alice!

// A callback function is passed as an argument to another function
function greetUser(callback) {
  console.log("Hi!");
  callback();
}

function sayBye() {
  console.log("Bye!");
}

greetUser(sayBye);
      
Hi!
Bye!

// Hoisting is JavaScript's default behavior of moving declarations to the top
console.log(x);  // Output: undefined
var x = 5;

sayHi();  // Output: Hi!
function sayHi() {
  console.log("Hi!");
}
      
undefined
Hi!

// 'this' refers to the object it belongs to
const person = {
  name: "Bob",
  greet: function() {
    return "Hello " + this.name;
  }
};

console.log(person.greet());  // Output: Hello Bob
      
Hello Bob

// Arrow function syntax is shorter than traditional functions
const add = (a, b) => a + b;
console.log(add(3, 4));  // Output: 7
      
7

// An object is a collection of key-value pairs
const car = {
  brand: "Toyota",
  model: "Camry",
  year: 2020
};

console.log(car.model);  // Output: Camry
      
Camry

// An array is a list-like object
let fruits = ["Apple", "Banana", "Cherry"];
console.log(fruits[1]);  // Output: Banana
      
Banana

// Template literals use backticks and can embed variables
let name = "Sam";
let greeting = `Hello, ${name}!`;
console.log(greeting);  // Output: Hello, Sam!
      
Hello, Sam!

// undefined: variable declared but not assigned
let x;
console.log(x);  // Output: undefined

// null: intentional absence of any value
let y = null;
console.log(y);  // Output: null
      
undefined
null

// Function declaration
function greet(name) {
  return "Hello " + name;
}

console.log(greet("Alice"));  // Output: Hello Alice
      
Hello Alice

// A function passed as argument to another function
function fetchData(callback) {
  setTimeout(() => {
    callback("Data received");
  }, 1000);
}

fetchData((message) => {
  console.log(message);  // Output: Data received
});
      
Data received

// Event bubbling: event propagates from child to parent elements
document.getElementById("child").addEventListener("click", () => {
  console.log("Child clicked");
});
document.getElementById("parent").addEventListener("click", () => {
  console.log("Parent clicked");
});

// Clicking child triggers both logs due to bubbling
      
(Click on elements to see console logs in browser)

// Creating and using a promise
const promise = new Promise((resolve, reject) => {
  setTimeout(() => {
    resolve("Success!");
  }, 1000);
});

promise.then(message => {
  console.log(message);  // Output: Success!
});
      
Success!

// == compares values after type coercion
console.log(5 == "5");  // Output: true

// === compares value and type strictly
console.log(5 === "5");  // Output: false
      
true
false

// Async function returns a promise
async function fetchData() {
  return "Data fetched";
}

// Using await to wait for promise
async function display() {
  const result = await fetchData();
  console.log(result);  // Output: Data fetched
}

display();
      
Data fetched

// Destructuring arrays
const arr = [1, 2, 3];
const [a, b] = arr;
console.log(a, b);  // Output: 1 2

// Destructuring objects
const obj = {x: 10, y: 20};
const {x, y} = obj;
console.log(x, y);  // Output: 10 20
      
1 2
10 20

// Exporting a function in a module (module.js)
export function greet() {
  return "Hello from module";
}

// Importing in another file
import { greet } from './module.js';
console.log(greet());  // Output: Hello from module
      
Hello from module

// Event loop manages execution of synchronous and asynchronous code
console.log("Start");

setTimeout(() => {
  console.log("Timeout");
}, 0);

console.log("End");

// Output order: Start, End, Timeout
      
Start
End
Timeout

// Closure: function remembers its lexical scope
function outer() {
  let count = 0;
  return function inner() {
    count++;
    console.log(count);
  };
}

const counter = outer();
counter();  // Output: 1
counter();  // Output: 2
      
1
2

// var is function-scoped and can be redeclared
var x = 1;
var x = 2;
console.log(x);  // Output: 2

// let is block-scoped and cannot be redeclared in same scope
let y = 1;
// let y = 2; // SyntaxError if uncommented
y = 3;
console.log(y);  // Output: 3

// const is block-scoped and cannot be reassigned
const z = 1;
// z = 2; // TypeError if uncommented
console.log(z);  // Output: 1
      
2
3
1

try {
  let a = 5;
  let b = a / 0; // Infinity, no error
  console.log(b);  // Output: Infinity

  throw new Error("Custom error"); // Throw an error manually
} catch (error) {
  console.log("Caught error:", error.message);
} finally {
  console.log("Always executes");
}
      
Infinity
Caught error: Custom error
Always executes

// Spread operator (...) copies elements or properties

// Arrays
const arr1 = [1, 2];
const arr2 = [...arr1, 3, 4];
console.log(arr2);  // Output: [1, 2, 3, 4]

// Objects
const obj1 = {a: 1, b: 2};
const obj2 = {...obj1, c: 3};
console.log(obj2);  // Output: {a:1, b:2, c:3}
      
[1, 2, 3, 4]
{a: 1, b: 2, c: 3}

// Template literals use backticks and allow interpolation
const name = "John";
const greeting = `Hello, ${name}!`;
console.log(greeting);  // Output: Hello, John!

// Multi-line string
const message = `This is
a multi-line
string.`;
console.log(message);
      
Hello, John!
This is
a multi-line
string.

// Arrow function syntax
const add = (x, y) => x + y;
console.log(add(2, 3));  // Output: 5

// Arrow functions do not have their own 'this'
const obj = {
  value: 10,
  getValue: function() {
    const inner = () => this.value;
    return inner();
  }
};
console.log(obj.getValue());  // Output: 10
      
5
10

// Class syntax for object creation
class Person {
  constructor(name) {
    this.name = name;
  }
  greet() {
    return `Hello, ${this.name}`;
  }
}

const p = new Person("Alice");
console.log(p.greet());  // Output: Hello, Alice
      
Hello, Alice

// Wait for multiple promises to resolve
const p1 = Promise.resolve(1);
const p2 = Promise.resolve(2);

Promise.all([p1, p2]).then(results => {
  console.log(results);  // Output: [1, 2]
});
      
[1, 2]

// Shallow clone using Object.assign()
const obj1 = {a:1, b:2};
const obj2 = Object.assign({}, obj1);
console.log(obj2);  // Output: {a:1, b:2}

// Using spread operator
const obj3 = {...obj1};
console.log(obj3);  // Output: {a:1, b:2}
      
{a: 1, b: 2}
{a: 1, b: 2}

// forEach iterates and returns undefined
const arr = [1,2,3];
arr.forEach(x => console.log(x * 2));  // Outputs 2,4,6

// map returns a new array
const doubled = arr.map(x => x * 2);
console.log(doubled);  // Output: [2,4,6]
      
2
4
6
[2, 4, 6]

// Variables and functions are hoisted

console.log(foo);  // Output: undefined
var foo = 5;

bar();  // Output: "Hello"

function bar() {
  console.log("Hello");
}
      
undefined
Hello

// Closure is a function that remembers its lexical scope
function outer() {
  let count = 0;
  return function inner() {
    count++;
    return count;
  };
}
const counter = outer();
console.log(counter());  // Output: 1
console.log(counter());  // Output: 2
      
1
2

// Event delegation allows attaching one event listener on a parent
document.getElementById("parent").addEventListener("click", function(e) {
  if (e.target && e.target.matches("button.child")) {
    console.log("Child button clicked:", e.target.textContent);
  }
});
      
Child button clicked: Button 1
Child button clicked: Button 2

// == does type coercion; === checks strict equality
console.log(5 == "5");   // true (type coercion)
console.log(5 === "5");  // false (strict type and value check)
      
true
false

// async function returns a promise
async function fetchData() {
  const data = await Promise.resolve("Data loaded");
  console.log(data);
}
fetchData();  // Output: Data loaded
      
Data loaded

// Generator functions use function* and yield keyword
function* gen() {
  yield 1;
  yield 2;
  yield 3;
}
const iterator = gen();
console.log(iterator.next().value);  // Output: 1
console.log(iterator.next().value);  // Output: 2
console.log(iterator.next().value);  // Output: 3
      
1
2
3

// Extract values from arrays or properties from objects
const [a, b] = [10, 20];
console.log(a, b);  // Output: 10 20

const {name, age} = {name: "Bob", age: 30};
console.log(name, age);  // Output: Bob 30
      
10 20
Bob 30

let a;
console.log(a);       // Output: undefined (not assigned)

let b = null;
console.log(b);       // Output: null (explicitly no value)
      
undefined
null

// Event loop manages execution of synchronous and asynchronous code
console.log("Start");
setTimeout(() => console.log("Timeout"), 0);
console.log("End");

// Output:
// Start
// End
// Timeout (after current call stack is empty)
      
Start
End
Timeout

// Exporting and importing modules (ES6 syntax)

// file math.js
export function add(x, y) {
  return x + y;
}

// file app.js
import { add } from './math.js';
console.log(add(2, 3));  // Output: 5
      
5

// Memoization caches function results to improve performance
function memoize(fn) {
  const cache = {};
  return function(arg) {
    if (cache[arg]) {
      return cache[arg];
    }
    const result = fn(arg);
    cache[arg] = result;
    return result;
  };
}
const factorial = memoize(function(n) {
  return n <= 1 ? 1 : n * factorial(n - 1);
});
console.log(factorial(5));  // Output: 120
      
120

// Split string, reverse array, join back
function reverseString(str) {
  return str.split('').reverse().join('');
}
console.log(reverseString("hello"));  // Output: "olleh"
      
olleh

function isPrime(num) {
  if (num <= 1) return false;
  for (let i = 2; i <= Math.sqrt(num); i++) {
    if (num % i === 0) return false;
  }
  return true;
}
console.log(isPrime(11));  // Output: true
console.log(isPrime(12));  // Output: false
      
true
false

function removeDuplicates(arr) {
  return [...new Set(arr)];
}
console.log(removeDuplicates([1,2,2,3,4,4,5]));  // Output: [1,2,3,4,5]
      
[1, 2, 3, 4, 5]

function factorial(n) {
  if (n <= 1) return 1;
  return n * factorial(n - 1);
}
console.log(factorial(5));  // Output: 120
      
120

// Use flat() method with Infinity for deep flattening
const nested = [1, [2, [3, 4], 5], 6];
const flat = nested.flat(Infinity);
console.log(flat);  // Output: [1,2,3,4,5,6]
      
[1, 2, 3, 4, 5, 6]

function randomBetween(min, max) {
  return Math.floor(Math.random() * (max - min + 1)) + min;
}
console.log(randomBetween(1, 10));  // Output: random integer between 1 and 10
      
7

const str = "Hello world";
console.log(str.includes("world"));  // Output: true
console.log(str.includes("bye"));    // Output: false
      
true
false

const arr1 = [1, 2];
const arr2 = [3, 4];
const merged = [...arr1, ...arr2];
console.log(merged);  // Output: [1,2,3,4]
      
[1, 2, 3, 4]

// Debounce delays function call until after wait time
function debounce(func, wait) {
  let timeout;
  return function(...args) {
    clearTimeout(timeout);
    timeout = setTimeout(() => func.apply(this, args), wait);
  };
}
const debouncedLog = debounce(() => console.log("Debounced!"), 300);
debouncedLog();
debouncedLog();
// "Debounced!" will log once after 300ms
      
Debounced!

// Using structuredClone (modern) or JSON methods (limitations apply)
const obj = {a:1, b:{c:2}};
const clone = structuredClone(obj);  // Modern browsers
console.log(clone);
      
{a:1, b:{c:2}}

function capitalizeWords(str) {
  return str.split(' ').map(word => word[0].toUpperCase() + word.slice(1)).join(' ');
}
console.log(capitalizeWords("hello world from js"));  // Output: "Hello World From Js"
      
Hello World From Js

// Array of objects to be sorted by age
const users = [
  {name: "Alice", age: 25},
  {name: "Bob", age: 20},
  {name: "Charlie", age: 30}
];
users.sort((a, b) => a.age - b.age);  // Sort by age ascending
console.log(users);  // Output sorted array
      
[ {name: "Bob", age: 20},
{name: "Alice", age: 25},
{name: "Charlie", age: 30}
]

// Function to check if object has no properties
function isEmpty(obj) {
  return Object.keys(obj).length === 0;  // Check keys count
}
console.log(isEmpty({}));       // true, empty object
console.log(isEmpty({a: 1}));  // false, has property
      
true
false

// Number to convert
const num = 10;
const binary = num.toString(2);  // Convert to binary string
console.log(binary);  // Output: "1010"
      
1010

// Compare two arrays element by element
function arraysEqual(a, b) {
  if (a.length !== b.length) return false;  // Different lengths
  for (let i = 0; i < a.length; i++) {
    if (a[i] !== b[i]) return false;  // Found mismatch
  }
  return true;  // All elements equal
}
console.log(arraysEqual([1,2,3], [1,2,3]));  // true
console.log(arraysEqual([1,2], [1,2,3]));    // false
      
true
false

// Shallow clone an object using spread syntax
const original = {a: 1, b: 2};
const clone = {...original};
console.log(clone);  // Output: {a: 1, b: 2}
      
{a: 1, b: 2}

// Debounce delays function call until user stops calling it
function debounce(func, delay) {
  let timeoutId;
  return function(...args) {
    clearTimeout(timeoutId);  // Clear previous timeout
    timeoutId = setTimeout(() => func.apply(this, args), delay);  // Set new timeout
  };
}

const log = () => console.log('Debounced!');
const debouncedLog = debounce(log, 1000);

debouncedLog();
debouncedLog();
debouncedLog();  // Only last call after 1 second runs
      
Debounced!

// Nested array with multiple levels
const nested = [1, [2, [3, 4], 5], 6];
const flat = nested.flat(2);  // Flatten array to depth 2
console.log(flat);  // Output: [1, 2, 3, 4, 5, 6]
      
[1, 2, 3, 4, 5, 6]

// Remove duplicates by converting to Set and back to array
const numbers = [1, 2, 2, 3, 4, 4, 5];
const unique = [...new Set(numbers)];
console.log(unique);  // Output: [1, 2, 3, 4, 5]
      
[1, 2, 3, 4, 5]

// Create a new Date object representing the current date and time
const now = new Date();

// Print the full date and time as a string
console.log(now.toString());  // Example output: "Sat May 18 2025 14:23:45 GMT+0000 (Coordinated Universal Time)"
      
Sat May 18 2025 14:23:45 GMT+0000 (Coordinated Universal Time)

// Function to generate a random integer between min and max (inclusive)
function randomBetween(min, max) {
  // Math.random() returns a decimal between 0 and 1
  // Multiply by the range size (max - min + 1), then add min
  // Use Math.floor() to round down to nearest whole number
  return Math.floor(Math.random() * (max - min + 1)) + min;
}

// Generate a random number between 1 and 10
console.log(randomBetween(1, 10));  // Example output: 7 (varies on each run)
      
7

// Define a string
const str = "Hello, world!";

// Check if 'world' is present in the string
console.log(str.includes("world"));  // true

// Check if 'bye' is present in the string
console.log(str.includes("bye"));    // false
      
true
false

// Function to capitalize the first character of a string
function capitalize(str) {
  // Get first character, convert to uppercase
  // Add the rest of the string unchanged
  return str.charAt(0).toUpperCase() + str.slice(1);
}

// Test the function with "hello"
console.log(capitalize("hello"));  // Output: "Hello"
      
Hello

// Define a string with spaces at start and end
const str = "   Hello World!   ";

// Use the trim() method to remove leading and trailing spaces
const trimmed = str.trim();

// Print the trimmed string
console.log(trimmed);  // Output: "Hello World!"
      
Hello World!

// Define two objects with some overlapping keys
const obj1 = {a: 1, b: 2};
const obj2 = {b: 3, c: 4};

// Merge objects using the spread operator
// Properties in obj2 will override those in obj1 if keys clash
const merged = {...obj1, ...obj2};

// Print the merged object
console.log(merged);  // Output: {a: 1, b: 3, c: 4}
      
{a: 1, b: 3, c: 4}

// Define an array and a non-array variable
const arr = [1, 2, 3];
const notArr = {a: 1};

// Use Array.isArray() to check
console.log(Array.isArray(arr));     // true
console.log(Array.isArray(notArr));  // false
      
true
false

// Define a numeric string
const numStr = "123";

// Convert string to integer using parseInt()
const num = parseInt(numStr, 10);

console.log(num);  // Output: 123
console.log(typeof num);  // Output: number
      
123
number

// Create a promise that resolves after 1 second
const myPromise = new Promise((resolve, reject) => {
  setTimeout(() => {
    resolve("Promise resolved!");
  }, 1000);
});

// Use .then() to handle the resolved value
myPromise.then(message => {
  console.log(message);  // Output after 1 second: "Promise resolved!"
});
      
Promise resolved!

// Define an object with nested objects
const original = {a: 1, b: {c: 2}};

// Deep clone using JSON methods (works if no functions or undefined)
const clone = JSON.parse(JSON.stringify(original));

// Modify clone
clone.b.c = 3;

// Print both objects to see that original is unchanged
console.log(original.b.c);  // Output: 2
console.log(clone.b.c);     // Output: 3
      
2
3

// Debounce function: delays execution until no calls for delay ms
function debounce(func, delay) {
  let timeoutId;
  return function(...args) {
    clearTimeout(timeoutId);
    timeoutId = setTimeout(() => {
      func.apply(this, args);
    }, delay);
  };
}

// Example usage: debounce logging of input
const debouncedLog = debounce((msg) => {
  console.log(msg);
}, 1000);

// Call multiple times quickly, logs only last after 1 sec
debouncedLog("First");
debouncedLog("Second");
debouncedLog("Third");  // Only "Third" will log after 1 second
      
Third

// Throttle function: ensures func is called at most once every delay ms
function throttle(func, delay) {
  let lastCall = 0;
  return function(...args) {
    const now = Date.now();
    if (now - lastCall >= delay) {
      lastCall = now;
      func.apply(this, args);
    }
  };
}

// Example usage: throttle logging
const throttledLog = throttle((msg) => {
  console.log(msg);
}, 1000);

// Call multiple times quickly, logs immediately then ignores calls for 1 sec
throttledLog("First");
throttledLog("Second");
setTimeout(() => throttledLog("Third"), 1100);  // "Third" logs after 1.1 sec
      
First
Third

const text = "Hello, world!";
const substring = "world";

// Using includes()
console.log(text.includes(substring));  // Output: true

// Using indexOf()
console.log(text.indexOf(substring) !== -1);  // Output: true
      
true
true

const arr1 = [1, 2, 3];
const arr2 = [4, 5, 6];

// Using concat()
const merged1 = arr1.concat(arr2);
console.log(merged1);  // Output: [1, 2, 3, 4, 5, 6]

// Using spread operator
const merged2 = [...arr1, ...arr2];
console.log(merged2);  // Output: [1, 2, 3, 4, 5, 6]
      
[1, 2, 3, 4, 5, 6]
[1, 2, 3, 4, 5, 6]

const numbers = [5, 10, 2, 8];

// Using Math.max with spread operator
const max = Math.max(...numbers);
console.log(max);  // Output: 10
      
10

// Generate random integer between min and max (inclusive)
function getRandomInt(min, max) {
  min = Math.ceil(min);
  max = Math.floor(max);
  return Math.floor(Math.random() * (max - min + 1)) + min;
}

// Example usage:
console.log(getRandomInt(1, 10));  // Output: a number between 1 and 10
      
(Outputs a random number between 1 and 10)