DEV Community

Cover image for If you think you know Javascript , try these🙄
keshav Sandhu
keshav Sandhu

Posted on

If you think you know Javascript , try these🙄

Here are some advanced-level JavaScript interview questions that test your understanding of core concepts like closures, asynchronous programming, event loops, data structures, and advanced logical reasoning:

1. Explain the concept of closures. Can you provide an example of a closure, and what are its practical use cases?

Answer:
Closures allow a function to access variables from an outer function even after the outer function has finished executing.

Example:

function outerFunction() {
    let count = 0;
    return function innerFunction() {
        count++;
        console.log(count);
    };
}

const counter = outerFunction();
counter(); // 1
counter(); // 2
Enter fullscreen mode Exit fullscreen mode

Here, innerFunction is a closure, which captures and remembers the count variable from its lexical scope even after outerFunction has finished execution.

Use cases:

  • Data privacy (encapsulation).
  • Function factories.
  • Currying.

2. What will the following code output and why?

for (var i = 0; i < 5; i++) {
  setTimeout(function() {
    console.log(i);
  }, 1000);
}
Enter fullscreen mode Exit fullscreen mode

Answer:
The output will be 5 five times after 1 second.

Explanation:
This happens because var is function-scoped, so when the setTimeout callback executes, the loop has already completed, and the value of i is 5. Each function inside setTimeout shares the same i.

Fix:
If you want to print 0, 1, 2, 3, 4, you can use let (block-scoped) or IIFE (Immediately Invoked Function Expression).

for (let i = 0; i < 5; i++) {
  setTimeout(function() {
    console.log(i);
  }, 1000);
}

// OR with IIFE:
for (var i = 0; i < 5; i++) {
  (function(i) {
    setTimeout(function() {
      console.log(i);
    }, 1000);
  })(i);
}
Enter fullscreen mode Exit fullscreen mode

3. What is the output of the following code?

console.log(1);

setTimeout(function() {
    console.log(2);
}, 1000);

setTimeout(function() {
    console.log(3);
}, 0);

console.log(4);
Enter fullscreen mode Exit fullscreen mode

Answer:

1
4
3
2
Enter fullscreen mode Exit fullscreen mode

Explanation:

  • 1 and 4 are logged immediately because they are synchronous.
  • setTimeout with 0 still goes to the event queue and is executed after the main thread finishes, so 3 is logged next.
  • 2 is logged after a 1-second delay.

4. How would you implement a function debounce in JavaScript?

Answer:
Debouncing ensures that a function is invoked only after a specified time has passed since the last time it was invoked, useful in limiting the number of times a function is called in quick succession (e.g., when resizing a window or typing in a search box).

Implementation:

function debounce(func, delay) {
    let timeoutId;
    return function(...args) {
        clearTimeout(timeoutId);
        timeoutId = setTimeout(() => func.apply(this, args), delay);
    };
}

// Usage:
const log = () => console.log('Function executed!');
const debouncedLog = debounce(log, 2000);
window.addEventListener('resize', debouncedLog);
Enter fullscreen mode Exit fullscreen mode

5. What is the difference between call, apply, and bind?

Answer:

  • call: Invokes a function with a specified this context and arguments passed individually.
  • apply: Similar to call, but arguments are passed as an array.
  • bind: Returns a new function that, when invoked, has its this context set to the specified value. The function can be invoked later.
function example(a, b) {
    console.log(this.name, a, b);
}

const obj = { name: 'Alice' };

// Using call
example.call(obj, 1, 2); // Output: Alice 1 2

// Using apply
example.apply(obj, [1, 2]); // Output: Alice 1 2

// Using bind
const boundFunc = example.bind(obj, 1, 2);
boundFunc(); // Output: Alice 1 2
Enter fullscreen mode Exit fullscreen mode

6. Write a function to flatten a deeply nested array.

Answer:
Using recursion to flatten an array:

function flattenArray(arr) {
    return arr.reduce((acc, val) => 
        Array.isArray(val) ? acc.concat(flattenArray(val)) : acc.concat(val), []
    );
}

// Example:
const nestedArray = [1, [2, [3, 4], [5]], 6];
console.log(flattenArray(nestedArray)); 
// Output: [1, 2, 3, 4, 5, 6]
Enter fullscreen mode Exit fullscreen mode

Alternatively, using ES6 flat method:

const flattened = nestedArray.flat(Infinity);
Enter fullscreen mode Exit fullscreen mode

7. How would you implement a function to deep clone an object?

Answer:
A deep clone creates a completely new copy of an object, including nested objects.

Implementation:

function deepClone(obj) {
    if (obj === null || typeof obj !== 'object') {
        return obj;
    }

    if (Array.isArray(obj)) {
        return obj.map(deepClone);
    }

    const clonedObj = {};
    for (let key in obj) {
        if (obj.hasOwnProperty(key)) {
            clonedObj[key] = deepClone(obj[key]);
        }
    }
    return clonedObj;
}

// Example:
const original = { a: 1, b: { c: 2, d: [3, 4] } };
const copy = deepClone(original);
console.log(copy); // Deeply copied object
Enter fullscreen mode Exit fullscreen mode

8. Explain the concept of promises and how you would implement a Promise.all function from scratch.

Answer:
Promise.all takes an array of promises and returns a single promise that resolves when all promises resolve, or rejects if any promise rejects.

Custom Implementation:

function customPromiseAll(promises) {
    return new Promise((resolve, reject) => {
        let results = [];
        let completed = 0;

        promises.forEach((promise, index) => {
            Promise.resolve(promise).then(result => {
                results[index] = result;
                completed++;
                if (completed === promises.length) {
                    resolve(results);
                }
            }).catch(reject);
        });
    });
}

// Example:
const p1 = Promise.resolve(1);
const p2 = Promise.resolve(2);
const p3 = Promise.resolve(3);

customPromiseAll([p1, p2, p3]).then(console.log);  // Output: [1, 2, 3]
Enter fullscreen mode Exit fullscreen mode

9. What will the following code output?

const obj = {
  message: 'Hello',
  getMessage() {
    const message = 'Hi';
    return this.message;
  }
};

console.log(obj.getMessage());
Enter fullscreen mode Exit fullscreen mode

Answer:
Output: Hello

Explanation:
The function getMessage accesses this.message, which refers to the message property of the object obj, not the local message variable defined inside the function.


10. Explain event delegation in JavaScript and how would you implement it.

Answer:
Event delegation is a pattern where a single event listener is attached to a parent element, and it listens for events from its child elements by using event bubbling. This technique is useful when dynamically adding elements or when you have many child elements that require the same event handler.

Implementation:

document.querySelector('#parent').addEventListener('click', function(event) {
    if (event.target && event.target.matches('.child')) {
        console.log('Child element clicked:', event.target);
    }
});

// Example HTML:
// <div id="parent">
//   <div class="child">Child 1</div>
//   <div class="child">Child 2</div>
// </div>
Enter fullscreen mode Exit fullscreen mode

These questions should give you a strong foundation in advanced JavaScript concepts, helping you prepare for high-level technical interviews.

Top comments (0)