Skip to main content
15 min readIntermediate

JavaScript Interview Guide

Master JavaScript fundamentals, closures, promises, async/await, and common interview questions with code examples.

JavaScriptES6+AsyncClosures

Introduction

JavaScript is one of the most popular programming languages, and mastering it is essential for frontend development interviews. This guide covers the fundamental concepts, advanced topics, and common interview questions you'll encounter.

We'll explore closures, promises, async/await, event loop, and more with practical code examples to help you prepare effectively.

Closures

A closure is a function that has access to variables in its outer (enclosing) lexical scope, even after the outer function has returned. Closures are created every time a function is created.

function outerFunction(x) {
  // Outer function's variable
  const outerVariable = x;
  
  // Inner function (closure)
  function innerFunction(y) {
    console.log(outerVariable + y);
  }
  
  return innerFunction;
}

const closure = outerFunction(10);
closure(5); // Output: 15

In this example, `innerFunction` has access to `outerVariable` even after `outerFunction` has finished executing. This is a closure.

Common use cases for closures include:

Promises and Async/Await

Promises are objects that represent the eventual completion (or failure) of an asynchronous operation. They help avoid callback hell and make async code more readable.

// Creating a Promise
const myPromise = new Promise((resolve, reject) => {
  const success = true;
  
  if (success) {
    resolve('Operation completed successfully');
  } else {
    reject('Operation failed');
  }
});

// Using Promises
myPromise
  .then(result => console.log(result))
  .catch(error => console.error(error))
  .finally(() => console.log('Promise settled'));

Async/await is syntactic sugar built on top of Promises, making asynchronous code look and behave more like synchronous code.

// Async function
async function fetchUserData(userId) {
  try {
    const response = await fetch(`/api/users/${userId}`);
    const userData = await response.json();
    return userData;
  } catch (error) {
    console.error('Error fetching user:', error);
    throw error;
  }
}

// Using async/await
async function displayUser(userId) {
  const user = await fetchUserData(userId);
  console.log(user);
}

Event Loop

The Event Loop is what allows JavaScript to perform non-blocking operations. It continuously checks the call stack and the callback queue.

console.log('1');

setTimeout(() => {
  console.log('2');
}, 0);

Promise.resolve().then(() => {
  console.log('3');
});

console.log('4');

// Output: 1, 4, 3, 2
// Explanation:
// 1. '1' and '4' are synchronous, so they execute first
// 2. Promise callbacks (microtasks) execute before setTimeout (macrotasks)
// 3. '3' executes before '2'

Understanding the event loop is crucial for writing efficient asynchronous code and debugging timing issues.

Common Interview Questions

1. What is the difference between var, let, and const?

// var - function scoped, can be redeclared
var x = 1;
var x = 2; // No error

// let - block scoped, cannot be redeclared
let y = 1;
let y = 2; // Error: Identifier 'y' has already been declared

// const - block scoped, cannot be redeclared or reassigned
const z = 1;
z = 2; // Error: Assignment to constant variable

// However, const objects can have properties modified
const obj = { name: 'John' };
obj.name = 'Jane'; // This is allowed
obj = {}; // This is not allowed

2. Explain "this" keyword

The value of `this` depends on how a function is called:

// In a method, 'this' refers to the object
const person = {
  name: 'John',
  greet() {
    console.log(`Hello, I'm ${this.name}`);
  }
};
person.greet(); // "Hello, I'm John"

// In a regular function, 'this' refers to the global object (or undefined in strict mode)
function regularFunction() {
  console.log(this); // Window (or undefined in strict mode)
}

// Arrow functions don't have their own 'this'
const arrowFunction = () => {
  console.log(this); // Inherits 'this' from enclosing scope
};

3. What is hoisting?

Hoisting is JavaScript's behavior of moving declarations to the top of their scope before code execution.

// Variable hoisting
console.log(x); // undefined (not ReferenceError)
var x = 5;

// Function hoisting
sayHello(); // "Hello!" (works because function is hoisted)

function sayHello() {
  console.log('Hello!');
}

// let and const are hoisted but not initialized (Temporal Dead Zone)
console.log(y); // ReferenceError
let y = 5;

Best Practices

Here are some best practices for JavaScript interviews:

  • Always use const by default, let when you need to reassign, and avoid var
  • Understand the difference between == and === (strict equality)
  • Know how to handle errors with try-catch blocks
  • Be familiar with array methods: map, filter, reduce, forEach
  • Understand destructuring and spread operators
  • Know how to work with modules (import/export)
  • Practice explaining your code clearly