JavaScript Practice Questions
Beginner → Medium → Expert
Topics covered: Primitive Data Types • Variables • Updating Numbers • Constants • Booleans • Reference Types •
Hoisting • Strings & Methods • Template Literals • undefined • Math Object • Comparison Operators • Conditional
Statements
Instructions: Try to solve the questions yourself first. Answers are provided at the end of this PDF. Write your code in
a browser console or any JS environment and observe the results.
BEGINNER LEVEL QUESTIONS
1. Declare a variable age using let and assign it the number 25. Then update it to 26. Print both values.
2. Create a constant PI with the value 3.14. Try to reassign it and observe what happens (comment the
error).
3. Write a program that checks if a number stored in a variable is positive, negative, or zero using an if-else
statement.
4. Create a string variable with your name. Use a string method to convert it to uppercase and print it.
5. What is the output of the following code? Explain why.
[Link](typeof null);
[Link](typeof undefined);
6. Use a template literal to print: “My name is [yourName] and I am [age] years old.”
7. Declare a boolean variable isStudent and set it to true. Print a message based on its value using a
conditional statement.
8. Use the Math object to find the square root of 64 and the maximum of 10, 25, and 7.
9. Predict the output and explain:
[Link](5 == "5");
[Link](5 === "5");
10. What will be printed and why? (related to hoisting)
[Link](x);
var x = 10;
MEDIUM LEVEL QUESTIONS
1. Create a program that takes two numbers. Use comparison operators and conditional statements to print
which number is larger, or if they are equal. Also handle the case when either number is not a valid number
(use isNaN).
2. Write a function that accepts a string and returns a new string with the first and last characters swapped.
Use string methods. Handle cases where the string length is less than 2.
3. Explain the difference between primitive and reference types with an example using objects or arrays.
Show what happens when you assign one variable to another.
4. Predict the output and explain the concept of hoisting:
[Link](a);
[Link](b);
var a = 5;
let b = 10;
5. Create a program that generates a random integer between 1 and 100 (inclusive) using the Math object.
Then check a guess and tell if it is too high, too low, or correct.
6. Write code that checks whether a given year is a leap year using conditional statements and the modulo
operator.
7. Use template literals and string methods to create a nice formatted message:
Input: firstName = "john", lastName = "DOE", age = 28
Output should look like: “Hello, John Doe! You are 28 years old.”
8. What is the difference between null and undefined? Write code that demonstrates both.
9. Create a simple calculator that performs addition, subtraction, multiplication, or division based on a string
operator (+, -, *, /) using conditional statements (if-else or switch).
10. Explain what happens in this code and why the final values are different:
let num1 = 10;
let num2 = num1;
num1 = 20;
let obj1 = { value: 10 };
let obj2 = obj1;
[Link] = 20;
[Link](num1, num2);
[Link]([Link], [Link]);
EXPERT LEVEL QUESTIONS
1. Write a function that creates a shallow copy of an object containing only primitive values. Then explain
why a simple assignment doesn’t work and what would happen with nested objects.
2. Predict and fully explain the output of this code (hoisting + temporal dead zone + types):
[Link](typeof a);
[Link](typeof b);
[Link](typeof c);
var a = 1;
let b = 2;
const c = 3;
function test() {
[Link](x);
var x = 10;
[Link](y);
let y = 20;
}
test();
3. Create a robust number-guessing game:
• Generate a random number between 1 and 50.
• Allow up to 7 attempts.
• After each wrong guess, tell if the secret number is higher or lower.
• At the end, show how many attempts were used or that the player failed.
Use Math object, conditionals, and proper variable updates.
4. Write a function that takes a string and returns an object with the count of vowels and consonants. Ignore
spaces and make it case-insensitive. Use string methods and conditionals.
5. Explain and demonstrate the difference between == and === with at least 6 different pairs of values
(including null, undefined, empty string, 0, false, objects).
6. Create a program that converts a temperature:
• Accept a number and a unit (C or F).
• Convert Celsius ↔ Fahrenheit.
• Round to 1 decimal place using Math methods.
• Validate the unit and handle invalid input with clear messages.
7. What is the output? Explain every step carefully (involves hoisting, scope, and reference vs primitive):
var x = 10;
function change(a, b) {
a = 20;
[Link] = 30;
}
let obj = { prop: 5 };
change(x, obj);
[Link](x);
[Link]([Link]);
8. Build a mini “string analyzer”:
• Accept a string.
• Print: length, uppercase version, lowercase version, first 3 characters, last 3 characters, whether it starts
with a vowel, and the reversed string.
• Use template literals for clean output.
9. Write a function that safely updates a number only if the new value is greater than the current value and is
a valid number. Return true if updated, false otherwise. Handle edge cases like NaN, Infinity, strings, etc.
10. Advanced challenge: Create a simple inventory system using only the topics you’ve studied (variables,
objects as reference types, conditionals, Math, strings, template literals).
• Store an item name, quantity, and price.
• Allow “buying” (decrease quantity) or “restocking” (increase quantity) with validation.
• Print a nice formatted receipt/summary using template literals.
• Prevent negative quantities and invalid operations.
ANSWERS
Detailed solutions and explanations
BEGINNER LEVEL — ANSWERS
Question 1 — Answer
let age = 25;
[Link](age); // 25
age = age + 1; // or age += 1; or age++;
[Link](age); // 26
Explanation: We use let because the value needs to change. const cannot be reassigned. You can update
numbers using age = age + 1, age += 1, or age++.
Question 2 — Answer
const PI = 3.14;
[Link](PI); // 3.14
// Trying to reassign:
PI = 3.15; // TypeError: Assignment to constant variable.
Explanation: const creates a constant binding. You cannot reassign it. Note: Trying let PI = ... after declaring with
const gives a SyntaxError (redeclaration), while PI = newValue gives a TypeError (assignment to constant).
Question 3 — Answer
let check = 1;
if (check > 0) {
[Link]("Positive");
} else if (check === 0) {
[Link]("Zero");
} else {
[Link]("Negative");
}
Important: Always use === (or ==) for comparison. Using = is assignment and is a common beginner mistake.
After checking > 0 and === 0, the remaining case must be negative, so a simple else is cleaner.
Question 4 — Answer
let myName = "sourabh";
[Link]([Link]()); // SOURABH
// OR if you want to update the variable:
myName = [Link]();
[Link](myName); // SOURABH
Key Concept: Strings are immutable in JavaScript. Methods like toUpperCase() return a new string. They do
not change the original variable unless you reassign the result.
Question 5 — Answer
[Link](typeof null); // "object"
[Link](typeof undefined); // "undefined"
Explanation: typeof null returning "object" is a well-known historical bug in JavaScript that was never fixed for
backward compatibility. null is actually a primitive value. typeof undefined correctly returns "undefined".
Question 6 — Answer
let yourName = "Sourabh";
let age = 25;
[Link](`My name is ${yourName} and I am ${age} years old.`);
Template literals use backticks (`) and allow embedding expressions with ${}. They are much cleaner than string
concatenation with +.
Question 7 — Answer
let isStudent = true;
if (isStudent) {
[Link]("You are a student.");
} else {
[Link]("You are not a student.");
}
Booleans are often used directly in conditions. You can also write if (isStudent === true), but it is unnecessary.
Question 8 — Answer
[Link]([Link](64)); // 8
[Link]([Link](10, 25, 7)); // 25
Useful Math methods: [Link](), [Link](), [Link](), [Link](), [Link](), [Link](),
[Link](), [Link]().
Question 9 — Answer
[Link](5 == "5"); // true
[Link](5 === "5"); // false
== performs type coercion (converts types before comparing). === checks both value and type (strict equality).
Prefer === in almost all cases to avoid unexpected results.
Question 10 — Answer
[Link](x); // undefined
var x = 10;
Explanation (Hoisting): Variable declarations with var are hoisted to the top of their scope and initialized with
undefined. That is why you can access x before the line where it is assigned. The assignment (x = 10) still
happens later. Note: let and const are also hoisted but stay in the Temporal Dead Zone until the declaration is
reached.
MEDIUM LEVEL — ANSWERS
Question 1 — Answer
let num1 = 15;
let num2 = 20;
if (isNaN(num1) || isNaN(num2)) {
[Link]("Please enter valid numbers");
} else if (num1 > num2) {
[Link]("num1 is larger");
} else if (num2 > num1) {
[Link]("num2 is larger");
} else {
[Link]("Both numbers are equal");
}
Question 2 — Answer
function swapFirstLast(str) {
if ([Link] < 2) return str;
return str[[Link] - 1] + [Link](1, -1) + str[0];
}
[Link](swapFirstLast("hello")); // oellh
[Link](swapFirstLast("a")); // a
Question 3 — Answer
Primitives (number, string, boolean, null, undefined, symbol, bigint) are copied by value. Reference types
(objects, arrays, functions) are copied by reference (they point to the same memory location).
// Primitive
let a = 10;
let b = a;
a = 20;
[Link](a, b); // 20 10
// Reference
let obj1 = { x: 10 };
let obj2 = obj1;
obj1.x = 20;
[Link](obj1.x, obj2.x); // 20 20
Question 4 — Answer
[Link](a); // undefined
[Link](b); // ReferenceError: Cannot access 'b' before initialization
var a = 5;
let b = 10;
var is hoisted and initialized with undefined. let is hoisted but remains in the Temporal Dead Zone (TDZ) until the
declaration line is executed, so accessing it early throws a ReferenceError.
Question 5 — Answer
let secret = [Link]([Link]() * 100) + 1;
let guess = 42; // replace with actual guess
if (guess === secret) {
[Link]("Correct!");
} else if (guess > secret) {
[Link]("Too high");
} else {
[Link]("Too low");
}
Question 6 — Answer
let year = 2024;
if ((year % 4 === 0 && year % 100 !== 0) || year % 400 === 0) {
[Link](year + " is a leap year");
} else {
[Link](year + " is not a leap year");
}
Question 7 — Answer
let firstName = "john";
let lastName = "DOE";
let age = 28;
let formatted = `Hello, ${firstName[0].toUpperCase() + [Link](1).toLowerCase()}
${lastName[0].toUpperCase() + [Link](1).toLowerCase()}! You are ${age} years old.`;
[Link](formatted);
// Hello, John Doe! You are 28 years old.
Question 8 — Answer
undefined: A variable has been declared but not assigned a value (or a missing function argument / object
property).
null: An intentional absence of any object value. It is assigned by the programmer.
let a;
[Link](a); // undefined
[Link](typeof a); // "undefined"
let b = null;
[Link](b); // null
[Link](typeof b); // "object" (bug)
Question 9 — Answer
function calculate(a, b, operator) {
if (operator === "+") return a + b;
else if (operator === "-") return a - b;
else if (operator === "*") return a * b;
else if (operator === "/") {
if (b === 0) return "Cannot divide by zero";
return a / b;
} else {
return "Invalid operator";
}
}
Question 10 — Answer
// Output:
// 20 10
// 20 20
Primitives are copied by value, so changing num1 does not affect num2. Objects are copied by reference, so obj1
and obj2 point to the same object in memory. Changing [Link] also changes [Link].
EXPERT LEVEL — ANSWERS
Question 1 — Answer
function shallowCopy(obj) {
return { ...obj }; // or [Link]({}, obj)
}
let original = { name: "Sourabh", age: 25 };
let copy = shallowCopy(original);
[Link] = 30;
[Link]([Link]); // 25 (unchanged)
Simple assignment (let copy = original) only copies the reference. Both variables point to the same object. A
shallow copy creates a new object with the same top-level properties. Nested objects are still shared (not
deep-copied).
Question 2 — Answer
Output explanation:
• typeof a → "undefined" (var is hoisted and initialized with undefined)
• typeof b → "undefined" (interesting: typeof on a TDZ variable returns "undefined" in most engines, but
accessing the value throws)
• typeof c → "undefined" (same as let regarding typeof in TDZ in practice)
• Inside test(): [Link](x) → undefined (var hoisting inside function)
• [Link](y) → ReferenceError (let is in Temporal Dead Zone)
Question 3 — Answer (Core Logic)
let secret = [Link]([Link]() * 50) + 1;
let attempts = 0;
const maxAttempts = 7;
let guessedCorrectly = false;
// In a real program you would loop and get user input.
// Example single check:
function makeGuess(guess) {
attempts++;
if (guess === secret) {
guessedCorrectly = true;
[Link](`Correct! You took ${attempts} attempts.`);
} else if (guess > secret) {
[Link]("Too high");
} else {
[Link]("Too low");
}
if (attempts >= maxAttempts && !guessedCorrectly) {
[Link](`Failed! The number was ${secret}`);
}
}
Question 4 — Answer
function countLetters(str) {
str = [Link]().replace(/ /g, "");
let vowels = 0;
let consonants = 0;
const vowelSet = "aeiou";
for (let char of str) {
if ([Link](char)) vowels++;
else if (char >= "a" && char <= "z") consonants++;
}
return { vowels, consonants };
}
Question 5 — Answer
[Link](5 == "5"); // true (coercion)
[Link](5 === "5"); // false
[Link](0 == false); // true
[Link](0 === false); // false
[Link]("" == false); // true
[Link]("" === false); // false
[Link](null == undefined); // true
[Link](null === undefined); // false
[Link]({} == {}); // false (different references)
[Link]({} === {}); // false
Question 6 — Answer
function convertTemp(value, unit) {
if (typeof value !== "number" || isNaN(value)) {
return "Please provide a valid number";
}
unit = [Link]();
if (unit === "C") {
let f = (value * 9/5) + 32;
return [Link](f * 10) / 10 + "°F";
} else if (unit === "F") {
let c = (value - 32) * 5/9;
return [Link](c * 10) / 10 + "°C";
} else {
return "Unit must be C or F";
}
}
Question 7 — Answer
// Output:
// 10
// 30
• x is a primitive. Inside the function, parameter a receives a copy of the value. Changing a does not affect the
outer x.
• obj is a reference type. Parameter b receives the reference to the same object. Changing [Link] modifies the
original object.
Question 8 — Answer
function analyzeString(str) {
const vowels = "aeiouAEIOU";
const startsWithVowel = [Link](str[0]);
const reversed = [Link]("").reverse().join("");
[Link](`Length: ${[Link]}`);
[Link](`Uppercase: ${[Link]()}`);
[Link](`Lowercase: ${[Link]()}`);
[Link](`First 3: ${[Link](0, 3)}`);
[Link](`Last 3: ${[Link](-3)}`);
[Link](`Starts with vowel: ${startsWithVowel}`);
[Link](`Reversed: ${reversed}`);
}
Question 9 — Answer
function safeUpdate(current, newValue) {
if (typeof newValue !== "number" || isNaN(newValue) || !isFinite(newValue)) {
return false;
}
if (newValue > current) {
return true; // caller can then do: current = newValue
}
return false;
}
Question 10 — Answer (Simple Version)
let item = {
name: "Notebook",
quantity: 50,
price: 40
};
function buy(qty) {
if (qty <= 0 || isNaN(qty)) {
[Link]("Invalid quantity");
return;
}
if (qty > [Link]) {
[Link]("Not enough stock");
return;
}
[Link] -= qty;
[Link](`Bought ${qty} ${[Link]}(s). Remaining: ${[Link]}`);
}
function restock(qty) {
if (qty <= 0 || isNaN(qty)) {
[Link]("Invalid quantity");
return;
}
[Link] += qty;
[Link](`Restocked ${qty}. New quantity: ${[Link]}`);
}
function printSummary() {
[Link](`\n--- Inventory ---\nItem: ${[Link]}\nQty: ${[Link]}\nPrice:
■${[Link]}\n----------------`);
}
— End of Practice Sheet —
Keep practicing. The more you write and break code, the faster you learn!