Interview

10 JavaScript Puzzles Interview Questions and Answers

Sharpen your JavaScript skills with challenging puzzles designed to enhance problem-solving abilities and prepare for technical interviews.

JavaScript remains a cornerstone of web development, enabling dynamic and interactive user experiences. Its versatility extends beyond the browser, finding applications in server-side development with Node.js, mobile app development, and even desktop applications. Mastery of JavaScript is essential for developers aiming to create seamless, responsive, and efficient web applications.

This article delves into a series of JavaScript puzzles designed to challenge and refine your problem-solving skills. By working through these puzzles, you will enhance your understanding of JavaScript’s intricacies and be better prepared to tackle complex coding challenges in technical interviews.

JavaScript Puzzles Interview Questions and Answers

1. Write a function that demonstrates the use of closures to create a private counter.

Closures in JavaScript allow functions to access variables from another function’s scope, often used to create private variables or methods. To demonstrate this, we can write a function that returns an object with methods to manipulate a private counter variable.

function createCounter() {
    let count = 0; // Private variable

    return {
        increment: function() {
            count++;
            return count;
        },
        decrement: function() {
            count--;
            return count;
        },
        getCount: function() {
            return count;
        }
    };
}

const counter = createCounter();
console.log(counter.increment()); // 1
console.log(counter.increment()); // 2
console.log(counter.decrement()); // 1
console.log(counter.getCount());  // 1

2. Create a function that returns a promise which resolves after 2 seconds. Use this function to demonstrate chaining of promises.

Promises in JavaScript handle asynchronous operations, representing a value that may be available now, in the future, or never. Chaining promises allows for a sequence of asynchronous tasks in a readable way.

Here is a function that returns a promise resolving after 2 seconds:

function delay(ms) {
    return new Promise(resolve => setTimeout(resolve, ms));
}

To demonstrate chaining, use the then method to handle the resolved value and chain multiple operations:

delay(2000)
    .then(() => {
        console.log('Resolved after 2 seconds');
        return delay(2000);
    })
    .then(() => {
        console.log('Resolved after another 2 seconds');
    });

3. Given an array of numbers, write a function to return a new array with each number doubled.

To double each number in an array, use the map function in JavaScript. It creates a new array with the results of calling a provided function on every element.

Example:

function doubleArray(arr) {
    return arr.map(num => num * 2);
}

const numbers = [1, 2, 3, 4, 5];
const doubledNumbers = doubleArray(numbers);
console.log(doubledNumbers); // [2, 4, 6, 8, 10]

4. Implement a simple class hierarchy with a base class Animal and a derived class Dog. Include a method in each class.

Class inheritance in JavaScript allows creating a hierarchy of classes that share functionality. The base class contains properties and methods common to all derived classes, which can have additional properties or override existing ones.

Here is a simple example:

class Animal {
    constructor(name) {
        this.name = name;
    }

    speak() {
        console.log(`${this.name} makes a sound.`);
    }
}

class Dog extends Animal {
    constructor(name, breed) {
        super(name);
        this.breed = breed;
    }

    speak() {
        console.log(`${this.name} barks.`);
    }
}

const animal = new Animal('Generic Animal');
animal.speak(); // Generic Animal makes a sound.

const dog = new Dog('Rex', 'German Shepherd');
dog.speak(); // Rex barks.

5. Write a function that takes a string and throws an error if the string is empty. Use try-catch to handle the error.

To handle errors in JavaScript, use the try-catch block. This allows catching exceptions and handling them without crashing the program. Below is an example of a function that takes a string and throws an error if it’s empty, with a try-catch block to handle the error.

function checkString(str) {
    if (str === "") {
        throw new Error("The string is empty");
    }
    return "The string is not empty";
}

try {
    console.log(checkString("Hello, World!")); // The string is not empty
    console.log(checkString("")); // This will throw an error
} catch (error) {
    console.error(error.message); // The string is empty
}

6. Write a function that takes an array of numbers and returns the sum of all even numbers using functional programming techniques.

Functional programming in JavaScript emphasizes pure functions and avoiding side effects. Use the filter method to select even numbers and the reduce method to sum them.

function sumOfEvenNumbers(arr) {
    return arr.filter(num => num % 2 === 0).reduce((acc, num) => acc + num, 0);
}

console.log(sumOfEvenNumbers([1, 2, 3, 4, 5, 6])); // Output: 12

7. Write a curried function that takes three arguments and returns their sum.

Currying in functional programming transforms a function into a sequence of functions, each taking a single argument. This allows for more flexible and reusable code.

Example:

function curriedSum(a) {
    return function(b) {
        return function(c) {
            return a + b + c;
        };
    };
}

// Usage
const result = curriedSum(1)(2)(3); // 6

8. Write a function that flattens a nested array of any depth.

Flattening a nested array involves converting it into a single-level array. This is useful for processing data in a uniform structure. Use recursion to handle arrays of any depth.

function flattenArray(arr) {
    let result = [];
    arr.forEach(element => {
        if (Array.isArray(element)) {
            result = result.concat(flattenArray(element));
        } else {
            result.push(element);
        }
    });
    return result;
}

// Example usage:
const nestedArray = [1, [2, [3, [4]], 5]];
const flatArray = flattenArray(nestedArray);
console.log(flatArray); // Output: [1, 2, 3, 4, 5]

9. Write a higher-order function that takes a function and a list, and applies the function to each element of the list.

Higher-order functions take other functions as arguments or return them as output. They are commonly used for operations like mapping, filtering, and reducing lists.

Here is an example of a higher-order function that takes a function and a list, applying the function to each element:

function applyFunctionToList(func, list) {
    return list.map(func);
}

const numbers = [1, 2, 3, 4, 5];
const square = x => x * x;

const squaredNumbers = applyFunctionToList(square, numbers);
console.log(squaredNumbers); // [1, 4, 9, 16, 25]

10. Write a function that handles errors in asynchronous code using try-catch within an async function.

In JavaScript, handle errors in asynchronous code using try-catch blocks within an async function. This ensures errors during asynchronous operations are caught and handled, preventing application crashes.

Example:

async function fetchData(url) {
    try {
        let response = await fetch(url);
        if (!response.ok) {
            throw new Error('Network response was not ok');
        }
        let data = await response.json();
        return data;
    } catch (error) {
        console.error('There has been a problem with your fetch operation:', error);
    }
}

fetchData('https://api.example.com/data')
    .then(data => {
        if (data) {
            console.log(data);
        }
    });
Previous

10 Email Security Interview Questions and Answers

Back to Interview
Next

10 Artificial Neural Network Interview Questions and Answers