Logo Gerardo Perrucci - Full Stack Developer

Common JavaScript Junior Interview Questions Explained

JavaScript Interview

Understanding core JavaScript concepts is essential for acing a junior developer interview. This article covers common interview questions, providing explanations and code snippets to illustrate each concept.

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

var declares a function-scoped or globally-scoped variable, while let and const are block-scoped. const also prevents reassignment of the variable. Variables declared with var can be re-declared in the same scope and attach to the global object when declared globally, which may cause unexpected behavior. In contrast, let and const throw errors when re-declared in the same block and remain block-scoped.

var globalVar = 'old';
if (true) {
  var globalVar = 'new'; // Re-declared in the same scope
  let blockLet = 'block';
  const blockConst = 'constant';
}
console.log(globalVar); // 'new'

Sources:

2. Explain hoisting.

Hoisting is JavaScript's behavior of moving declarations to the top of their scope before code execution. Function declarations and variable declarations using var are hoisted, whereas let and const are not initialized until the code executes. During hoisting, declarations are moved but assignments stay in place. Calling a variable before assignment returns undefined. Only function declarations are fully hoisted, while function expressions and arrow functions behave like variables.

console.log(a); // undefined
var a = 5;

Source:

3. What are closures?

A closure occurs when a function retains access to its lexical scope even when executed outside that scope. Closures are commonly used for data privacy and creating factory functions. This ability to remember the surrounding scope allows functions to maintain private variables, enabling patterns like once functions, memoization, and currying.

function makeCounter() {
  let count = 0;
  return function () {
    count++;
    return count;
  };
}

const counter = makeCounter();
console.log(counter()); // 1
console.log(counter()); // 2

Source:

4. What is event bubbling?

Event bubbling is the propagation of events from the deepest target element upward through the DOM tree. You can stop propagation with event.stopPropagation(). Events first trigger on the innermost element, then bubble up to ancestors unless the handler stops propagation. The opposite phase is event capturing, which triggers handlers from the root down before the bubbling phase.

<div id="outer">
  <button id="inner">Click me</button>
</div>
const outer = document.getElementById('outer');
const inner = document.getElementById('inner');

outer.addEventListener('click', () => console.log('Outer clicked'));
inner.addEventListener('click', e => {
  console.log('Inner clicked');
  // e.stopPropagation(); // Uncomment to stop bubbling
});

Source:

5. How do promises and async/await handle asynchronous code?

Promises represent the eventual result of an asynchronous operation. async/await simplifies promise-based code by allowing asynchronous logic to be written in a synchronous style. They provide methods like then and catch for chaining actions once the asynchronous task finishes or fails. When used with async functions, you can handle errors using try/catch, making asynchronous code easier to read.

function fetchData() {
  return new Promise(resolve => {
    setTimeout(() => resolve('Done'), 1000);
  });
}

async function run() {
  const result = await fetchData();
  console.log(result); // 'Done'
}

run();

Sources:

6. What are the primitive data types in JavaScript?

JavaScript has seven primitive data types: string, number, bigint, boolean, undefined, symbol, and null. These types are immutable, meaning their values cannot be changed once created. Non-primitive types like objects and arrays are mutable and passed by reference.

const name = 'Jane';
const age = 30;
const big = 123n;
const active = true;
let unknown;
const id = Symbol('id');
const empty = null;

Source:

7. How does this work in JavaScript?

this is determined by how a function is called. In the global context, this refers to the global object (window in browsers). Inside an object method, this refers to that object. Arrow functions do not have their own this; they inherit it from the surrounding scope. Methods like call, apply, and bind can explicitly set the this value.

const obj = {
  value: 42,
  regular() {
    console.log(this.value); // 42
  },
  arrow: () => {
    console.log(this.value); // undefined in most cases
  },
};

obj.regular();
obj.arrow();

Source:

8. What is the difference between == and ===?

== compares values after performing type coercion, which can lead to unexpected results. === checks both value and type without coercion, making it the preferred choice for most comparisons.

0 == '0'; // true
0 === '0'; // false

Source:

9. Explain the event loop in JavaScript.

The event loop handles asynchronous operations by coordinating the call stack and task queues. When the stack is empty, the loop processes messages from the queue, executing callbacks. Promises use the microtask queue, which has priority over the macrotask queue used by setTimeout.

console.log('start');
setTimeout(() => console.log('timeout'), 0);
Promise.resolve().then(() => console.log('promise'));
console.log('end');
// Output: start, end, promise, timeout

Source:

10. What is destructuring assignment?

Destructuring allows extracting values from arrays or properties from objects into distinct variables, making code more concise and readable.

const [first, second] = [1, 2];
const { name, age } = { name: 'Jane', age: 30 };

Source:

References

  • MDN Web Docs – Comprehensive JavaScript documentation.
  • JavaScript.info – Tutorials and explanations on core JavaScript concepts.