JavaScript course
javascript programming language icon

JavaScript Exercises: 29 Practice Problems with Solutions

These problems walk from variables and loops through array methods, closures, classes and async code. Each one isolates a single idea so you can tell exactly what you did and did not understand.

Run your answer in the editor below. Anything you log with console.log appears in the output panel, just like a browser console.

Run your answer here

Type your solution, press Run, and use the Input box when a problem asks you to read from standard input.

JavaScript Compiler
Output
Code runs in a sandboxed preview inside your browser — your code is saved locally for next time.

How to practise so it actually sticks

Attempt the problem before opening the solution, even if your first version is clumsy. A working ugly answer teaches more than a beautiful one you read. When you get stuck for more than five minutes, read the hint — not the solution — and try again.

After you pass, open the solution and ask what is different about it. Shorter? Fewer variables? A built-in you did not know? That comparison is where most of the growth happens. Then change the problem slightly: sort the other direction, handle an empty input, read a value instead of hard-coding it.

Aim for three to five problems a day rather than thirty in one sitting. Spacing practice over days is what moves syntax from "I can look it up" to "my fingers know it".

The exercises

Showing 29 of 29 exercises.

  1. BeginnerBasics & output

    1. Greet a name

    Store the name "Ada" in a variable and log "Hello, Ada!".

    Hint: Template literals use backticks and ${}.

    const name = ;
    // log the greeting
    Show solution
    const name = "Ada";
    console.log(`Hello, ${name}!`);
  2. BeginnerBasics & output

    2. Swap two variables

    Given a = 3 and b = 8, swap them and log both values.

    Hint: Array destructuring: [a, b] = [b, a].

    let a = 3, b = 8;
    Show solution
    let a = 3, b = 8;
    [a, b] = [b, a];
    console.log(a, b);
  3. BeginnerBasics & output

    3. Inspect types

    Log the typeof 5, "5", true, null and undefined.

    Hint: typeof null is famously "object".

    Show solution
    console.log(typeof 5, typeof "5", typeof true, typeof null, typeof undefined);
  4. BeginnerNumbers & math

    4. Celsius to Fahrenheit

    Convert 37 degrees Celsius to Fahrenheit and log the result.

    Hint: F = C * 9 / 5 + 32.

    const c = 37;
    Show solution
    const c = 37;
    console.log(c * 9 / 5 + 32);
  5. BeginnerConditionals

    5. Even or odd

    Log "even" or "odd" for the number 17.

    Hint: Use the remainder operator %.

    const n = 17;
    Show solution
    const n = 17;
    console.log(n % 2 === 0 ? "even" : "odd");
  6. BeginnerConditionals

    6. Largest of three

    Log the largest of 12, 45 and 31 without using Math.max.

    Hint: Compare pairs with if/else.

    const a = 12, b = 45, c = 31;
    Show solution
    const a = 12, b = 45, c = 31;
    let max = a;
    if (b > max) max = b;
    if (c > max) max = c;
    console.log(max);
  7. BeginnerLoops

    7. FizzBuzz to 20

    Log 1..20, replacing multiples of 3 with "Fizz", of 5 with "Buzz" and both with "FizzBuzz".

    Hint: Check the 15 case first.

    for (let i = 1; i <= 20; i++) {
    }
    Show solution
    for (let i = 1; i <= 20; i++) {
      if (i % 15 === 0) console.log("FizzBuzz");
      else if (i % 3 === 0) console.log("Fizz");
      else if (i % 5 === 0) console.log("Buzz");
      else console.log(i);
    }
  8. BeginnerLoops

    8. Sum 1 to 100

    Use a loop to add every number from 1 to 100 and log the total.

    Hint: Keep a running total outside the loop.

    let total = 0;
    Show solution
    let total = 0;
    for (let i = 1; i <= 100; i++) total += i;
    console.log(total);
  9. BeginnerLoops

    9. Multiplication table

    Log the 7 times table from 7x1 to 7x10 as "7 x 3 = 21".

    Hint: One loop, template literal inside.

    Show solution
    for (let i = 1; i <= 10; i++) console.log(`7 x ${i} = ${7 * i}`);
  10. BeginnerStrings

    10. Reverse a string

    Reverse "javascript" and log it.

    Hint: split("") then reverse() then join("").

    const s = "javascript";
    Show solution
    const s = "javascript";
    console.log(s.split("").reverse().join(""));
  11. BeginnerStrings

    11. Count vowels

    Count the vowels in "Programming is fun" and log the count.

    Hint: Loop the characters and test membership in "aeiou".

    const text = "Programming is fun";
    Show solution
    const text = "Programming is fun";
    let n = 0;
    for (const ch of text.toLowerCase()) if ("aeiou".includes(ch)) n++;
    console.log(n);
  12. IntermediateStrings

    12. Palindrome check

    Write isPalindrome(s) that ignores case and spaces. Test it with "Never odd or even".

    Hint: Normalise first with replace(/\s/g, "").toLowerCase().

    function isPalindrome(s) {
    }
    Show solution
    function isPalindrome(s) {
      const t = s.toLowerCase().replace(/[^a-z0-9]/g, "");
      return t === t.split("").reverse().join("");
    }
    console.log(isPalindrome("Never odd or even"));
  13. IntermediateStrings

    13. Title-case a sentence

    Turn "the quick brown fox" into "The Quick Brown Fox".

    Hint: Split on spaces, capitalise each word, join back.

    const s = "the quick brown fox";
    Show solution
    const s = "the quick brown fox";
    console.log(s.split(" ").map(w => w[0].toUpperCase() + w.slice(1)).join(" "));
  14. BeginnerArrays

    14. Array statistics

    For [4, 9, 1, 7, 3] log the sum, the average, the smallest and the largest.

    Hint: reduce for the sum, Math.min/Math.max with spread.

    const nums = [4, 9, 1, 7, 3];
    Show solution
    const nums = [4, 9, 1, 7, 3];
    const sum = nums.reduce((a, b) => a + b, 0);
    console.log(sum, sum / nums.length, Math.min(...nums), Math.max(...nums));
  15. IntermediateArrays

    15. Filter then map

    From 1..20 keep the even numbers and log their squares.

    Hint: Array.from({length: 20}, (_, i) => i + 1).

    Show solution
    const nums = Array.from({ length: 20 }, (_, i) => i + 1);
    console.log(nums.filter(n => n % 2 === 0).map(n => n * n));
  16. IntermediateArrays

    16. Remove duplicates

    Remove duplicates from [1,2,2,3,4,4,4,5] keeping order.

    Hint: A Set preserves insertion order.

    const nums = [1, 2, 2, 3, 4, 4, 4, 5];
    Show solution
    const nums = [1, 2, 2, 3, 4, 4, 4, 5];
    console.log([...new Set(nums)]);
  17. IntermediateObjects

    17. Group words by length

    Group ["hi","cat","dog","tree","a"] into an object keyed by word length.

    Hint: reduce into an object, creating the array when missing.

    const words = ["hi", "cat", "dog", "tree", "a"];
    Show solution
    const words = ["hi", "cat", "dog", "tree", "a"];
    const byLen = words.reduce((acc, w) => {
      (acc[w.length] ||= []).push(w);
      return acc;
    }, {});
    console.log(byLen);
  18. IntermediateObjects

    18. Word frequency

    Count how often each word appears in "to be or not to be".

    Hint: Use a Map or plain object as a counter.

    const text = "to be or not to be";
    Show solution
    const text = "to be or not to be";
    const counts = {};
    for (const w of text.split(" ")) counts[w] = (counts[w] || 0) + 1;
    console.log(counts);
  19. IntermediateObjects

    19. Sort objects by field

    Sort [{n:'A',score:70},{n:'B',score:91},{n:'C',score:55}] by score descending and log the names.

    Hint: sort((a, b) => b.score - a.score).

    const rows = [{ n: 'A', score: 70 }, { n: 'B', score: 91 }, { n: 'C', score: 55 }];
    Show solution
    const rows = [{ n: 'A', score: 70 }, { n: 'B', score: 91 }, { n: 'C', score: 55 }];
    console.log([...rows].sort((a, b) => b.score - a.score).map(r => r.n));
  20. IntermediateFunctions

    20. Default and rest parameters

    Write sum(...nums) returning the total, and greet(name, greeting = "Hello").

    Hint: Rest parameters collect arguments into an array.

    Show solution
    const sum = (...nums) => nums.reduce((a, b) => a + b, 0);
    const greet = (name, greeting = "Hello") => `${greeting}, ${name}!`;
    console.log(sum(1, 2, 3), greet("Ada"));
  21. AdvancedFunctions

    21. Closure counter

    Write makeCounter() returning a function that increments a private count each call.

    Hint: The inner function closes over a variable in the outer scope.

    function makeCounter() {
    }
    Show solution
    function makeCounter() {
      let count = 0;
      return () => ++count;
    }
    const next = makeCounter();
    console.log(next(), next(), next());
  22. AdvancedFunctions

    22. Memoise a slow function

    Write memoize(fn) that caches results by argument, then memoise a recursive fibonacci.

    Hint: Keep a Map from argument to result.

    function memoize(fn) {
    }
    Show solution
    function memoize(fn) {
      const cache = new Map();
      return (n) => {
        if (cache.has(n)) return cache.get(n);
        const v = fn(n);
        cache.set(n, v);
        return v;
      };
    }
    const fib = memoize((n) => (n < 2 ? n : fib(n - 1) + fib(n - 2)));
    console.log(fib(40));
  23. IntermediateClasses

    23. A small class

    Write a BankAccount class with deposit, withdraw (refusing overdrafts) and a balance getter.

    Hint: Use #balance for a private field.

    class BankAccount {
    }
    Show solution
    class BankAccount {
      #balance = 0;
      deposit(n) { this.#balance += n; return this; }
      withdraw(n) {
        if (n > this.#balance) throw new Error("Insufficient funds");
        this.#balance -= n;
        return this;
      }
      get balance() { return this.#balance; }
    }
    const acc = new BankAccount();
    acc.deposit(100).withdraw(30);
    console.log(acc.balance);
  24. IntermediateErrors

    24. Handle a thrown error

    Parse the invalid JSON string "{oops}" inside try/catch and log a friendly message.

    Hint: JSON.parse throws a SyntaxError.

    const raw = "{oops}";
    Show solution
    const raw = "{oops}";
    try {
      console.log(JSON.parse(raw));
    } catch (err) {
      console.log("Could not read that data:", err.message);
    }
  25. AdvancedAsync

    25. Await in sequence

    Write delay(ms) returning a Promise, then await it three times logging a step each time.

    Hint: new Promise(res => setTimeout(res, ms)).

    Show solution
    const delay = (ms) => new Promise((res) => setTimeout(res, ms));
    (async () => {
      for (let i = 1; i <= 3; i++) {
        await delay(100);
        console.log("step", i);
      }
    })();
  26. AdvancedAsync

    26. Run promises in parallel

    Create three promises resolving to 1, 2 and 3 and log their sum using Promise.all.

    Hint: Promise.all takes an array and resolves to an array.

    Show solution
    const ps = [1, 2, 3].map((n) => Promise.resolve(n));
    Promise.all(ps).then((vals) => console.log(vals.reduce((a, b) => a + b, 0)));
  27. AdvancedAlgorithms

    27. Binary search

    Implement binary search over a sorted array and return the index or -1.

    Hint: Track low and high, compare the middle.

    function search(arr, target) {
    }
    Show solution
    function search(arr, target) {
      let lo = 0, hi = arr.length - 1;
      while (lo <= hi) {
        const mid = (lo + hi) >> 1;
        if (arr[mid] === target) return mid;
        if (arr[mid] < target) lo = mid + 1;
        else hi = mid - 1;
      }
      return -1;
    }
    console.log(search([1, 3, 5, 7, 9, 11], 9));
  28. AdvancedAlgorithms

    28. Flatten a nested array

    Flatten [1,[2,[3,[4]]],5] completely without using Array.prototype.flat.

    Hint: Recurse when an item is itself an array.

    function flatten(arr) {
    }
    Show solution
    function flatten(arr) {
      return arr.reduce((out, item) => out.concat(Array.isArray(item) ? flatten(item) : item), []);
    }
    console.log(flatten([1, [2, [3, [4]]], 5]));
  29. AdvancedAlgorithms

    29. Debounce a function

    Write debounce(fn, ms) that only runs fn after calls stop for ms milliseconds.

    Hint: clearTimeout the previous timer on each call.

    function debounce(fn, ms) {
    }
    Show solution
    function debounce(fn, ms) {
      let t;
      return (...args) => {
        clearTimeout(t);
        t = setTimeout(() => fn(...args), ms);
      };
    }
    const log = debounce((v) => console.log("ran with", v), 50);
    log(1); log(2); log(3);

What to do next

If a whole topic feels shaky, go back to that chapter in the 17-chapter JavaScript course and re-read it, then return here. When the advanced problems feel routine, take the final JavaScript quiz and claim your certificate, or open the JavaScript online compiler and build something of your own.