JavaScript
JS01

JS01 Exercises

Practical Exercises

  1. Write a function isLeapYear(number) that checks whether a given year is a leap year.
function isLeapYear(year) {
    // Check if the year is divisible by 4
    if (year % 4 !== 0) {
        return false;
    }
    // Check for century years which are not leap years unless divisible by 400
    if (year % 100 === 0) {
        return year % 400 === 0;
    }
    return true;
}
  1. Write a function calculate(x, y, op) that performs the operation op on the numbers x and y. For example calculate(3, 4, '+') should return 7.
function calculate(x, y, op) {
    switch (op) {
        case '+':
            return x + y;
        case '-':
            return x - y;
        case '*':
            return x * y;
        case '/':
            if (y === 0) {
                throw new Error("Cannot divide by zero");
            }
            return x / y;
        default:
            throw new Error("Invalid operator");
    }
}
  1. Write a function classifyAge(age) that accepts a number representing the age of a person and returns a string describing their age group:
  • Less than 13: 'Child'
  • 13 to 19: 'Teen'
  • 20 to 65: 'Adult'
  • More than 65: 'Senior'

The function should throw an error if age is negative

function classifyAge(age) {
    if (age < 0) {
        throw new Error("Age cannot be negative");
    } else if (age < 13) {
        return 'Child';
    } else if (age >= 13 && age <= 19) {
        return 'Teen';
    } else if (age >= 20 && age <= 65) {
        return 'Adult';
    } else {
        return 'Senior';
    }
}
  1. Write a function factorial(number) that returns the factorial of a number.
function factorial(number) {
    if (number < 0) {
        throw new Error("Factorial is not defined for negative numbers");
    }
    if (number === 0) {
        return 1;
    }
    let result = 1;
    for (let i = number; i > 1; i--) {
        result *= i;
    }
    return result;
}
  1. Write a function isPrime(number) that check whether a number is prime.
function isPrime(number) {
    if (number <= 1) {
        return false; // Numbers less than or equal to 1 are not prime
    }
 
    // Check from 2 to half of the number
    for (let i = 2; i <= number / 2; i++) {
        if (number % i === 0) {
            return false; // Number is divisible by some other number, so it's not prime
        }
    }
 
    return true; // Number is prime
 
}
 
  1. Extend the previous function by writing a function primes(n) that returns all prime numbers until n in a list.
function primes(n) {
    let primesArray = [];
    for (let num = 2; num <= n; num++) {
        if (isPrime(num)) {
            primesArray.push(num);
        }
    }
    return primesArray;
}
  1. Write a function repeat(str, n) that repeats a string n times.
function repeat(str, n) {
    let result = '';
    for (let i = 0; i < n; i++) {
        result += str;
    }
    return result;
}
  1. Write a function capitalizeFirstLetter(s) that capitalizes the first letter of a string.
function capitalizeFirstLetter(s) {
    if (s.length === 0) return s;
    return s.charAt(0).toUpperCase() + s.slice(1);
}
  1. Write a function sumOfDigits(number) that returns the sum of the digits of a number.
function sumOfDigits(number) {
    let sum = 0;
    let digits = Math.abs(number).toString();
 
    for (let digit of digits) {
        sum += parseInt(digit, 10);
    }
 
    return sum;
 
}
 
  1. Write a function encryptCaesar(str, shift) that takes a string and a shift value and encrypts the string according to the Caesar algorithm.
function encryptCaesar(str, shift) {
    let encrypted = "";
 
    for (let char of str) {
        if (char.match(/[a-z]/i)) {
            let code = char.charCodeAt(0);
 
            // Uppercase letters
            if (code >= 65 && code <= 90) {
                char = String.fromCharCode(((code - 65 + shift) % 26) + 65);
            }
            // Lowercase letters
            else if (code >= 97 && code <= 122) {
                char = String.fromCharCode(((code - 97 + shift) % 26) + 97);
            }
        }
        encrypted += char;
    }
 
    return encrypted;
}

Theoretical Questions

  1. What is the difference between var, let and const? When should you use what?

var declares a variable with function scope and can be redeclared or updated. let and const are block-scoped (limited to their enclosing block), introduced in ES6; let allows updating but not redeclaration, while const is for immutable bindings and cannot be updated or redeclared. Use let for variables whose values change, const for constants, and avoid var for modern JavaScript to prevent scope-related issues.

  1. What is the difference between the == and === operators?

The == operator performs equality comparison with type coercion, meaning it converts the operands to the same type before comparison. The === operator, known as the strict equality operator, compares both value and type without doing any type conversion. Use === for predictable comparisons as it avoids the potential for confusing and unexpected results due to type coercion.

  1. Explain the ternary operator ? :

The ternary operator ? : in JavaScript is a concise way to perform conditional (if-else) statements. It takes three operands: a condition followed by a question mark (?), the expression to execute if the condition is true, then a colon (:), and the expression to execute if the condition is false. Syntax: condition ? expressionIfTrue : expressionIfFalse. It's useful for short, inline conditional logic.

  1. What is the nullish coalescing operator for?

The nullish coalescing operator ?? in JavaScript is used to return the right-hand operand when the left-hand operand is null or undefined, and otherwise returns the left-hand operand. It's useful for assigning default values while avoiding the pitfalls of falsy values like 0 or an empty string being treated as null/undefined.

  1. How can you convert a function declaration to an arrow function expression and vice versa?

Convert a function declaration to an arrow function by removing function, adding => after the arguments, and optionally omitting {} and return for single expressions. Convert an arrow function to a function declaration by adding function, removing =>, and enclosing the body in {} with a return statement if needed.

  1. What is an anonymous functions and why are they useful?

An anonymous function is a function without a name, often used as an argument to other functions or as an immediately invoked function expression (IIFE). They are useful for short-lived, single-use operations, reducing the namespace clutter and providing functional programming capabilities, like callbacks in event handlers or with array methods (e.g., map, filter).

  1. What do try and catch do?

try and catch are used in JavaScript for error handling. try wraps a block of code that might throw an error, and catch is used to define a response if an error occurs. If an error is thrown in the try block, the code in the catch block is executed, allowing for graceful handling of exceptions.