Full-Stack Prep written-test notes with working examples

MODULE 01

JavaScript

The written round leans on closures, hoisting, the event loop and coercion. Learn to answer in one sentence, then back it with a two-line example.

Write these answers

var vs let vs const

var is function-scoped and hoisted with value undefined. let and const are block-scoped and uninitialized until declared (the temporal dead zone). const forbids reassignment, but not mutation of the object it holds.

== vs ===

== compares values after coercing types, so "5" == 5 is true. === compares type and value, so "5" === 5 is false. Default to ===.

Closure

A function that remembers the variables of the scope it was created in, even after its outer function has returned. It is how you build private state — counters, caches, once() helpers.

Hoisting

Declarations are moved to the top of their scope before execution. Only the declaration is hoisted, not the assignment: var reads undefined early, let/const throw a ReferenceError.

Promise and async/await

A Promise is a future value with three states: pending → fulfilled | rejected. async/await is syntax over promises — await pauses inside an async function until it settles; errors are caught with try/catch.

Event loop

JS runs one call stack. When it empties, the event loop drains all microtasks (promise callbacks) first, then takes one macrotask (setTimeout, I/O). That is why a resolved promise wins over setTimeout(…, 0).

map / filter / reduce

map returns a new array of the same length, transformed. filter returns a new array of the items that passed a test. reduce folds the array into one value — a sum, an object, anything.

null vs undefined

undefined: declared but no value assigned (also missing arguments). null: an intentional empty value set by the programmer.

Working examples

closure.js
// A closed-over variable + returns it 
function makeCounter() {
  let count = 0;              // private — nothing outside can touch it
  return function () {
    count += 1;
    return count;
  };
}

const c = makeCounter();
console.log(c()); // 1
console.log(c()); // 2
console.log(c()); // 3
async-await.js
// Fetch a user and handle errors the way graders expect
async function getUser(id) {
  try {
    const res = await fetch(`/api/users/${id}`);
    if (!res.ok) throw new Error(`HTTP ${res.status}`);
    const data = await res.json();
    return data;
  } catch (err) {
    console.error("Failed:", err.message);
    return null;
  }
}
getUser(1);
array-methods.js
// filter today, take prices, add them up — in one chain
const items = [
  { name: "pen",    price: 20,  inStock: true  },
  { name: "bag",    price: 500, inStock: true  },
  { name: "eraser", price: 5,   inStock: false },
];

const total = items
  .filter((i) => i.inStock)
  .map((i) => i.price)
  .reduce((sum, p) => sum + p, 0);

console.log(total); // 520
this-call-bind-apply.js
// call, bind, apply — all fix what `this` points to
const person = { name: "Afjal", greet() { return "Hi " + this.name; } };

console.log(person.greet());                      // Hi Afjal
console.log(person.greet.call({ name: "Sam" }));  // Hi Sam  — args passed one by one
console.log(person.greet.apply({ name: "Ria" })); // Hi Ria  — args passed as an array

const g = person.greet.bind({ name: "Dev" });     // bind returns a new function
console.log(g());                                 // Hi Dev
debounce.js
// debounce: run fn only after the calls have stopped for `ms`
function debounce(fn, ms) {
  let timer;
  return function (...args) {          // closure keeps `timer` private
    clearTimeout(timer);
    timer = setTimeout(() => fn.apply(this, args), ms);
  };
}

const onType = debounce((q) => console.log("searching:", q), 500);

onType("h");    // wait…
onType("ha");   // restart the timer…
onType("hai");  // …only this one runs, 500ms after the last call
promise-all.js
// fire requests in parallel, wait for all — fails fast on the first error
async function loadAll() {
  try {
    const [user, posts] = await Promise.all([
      fetch("/api/users/1").then((r) => r.json()),
      fetch("/api/posts").then((r) => r.json()),
    ]);
    console.log(user.name, posts.length);
  } catch (err) {
    console.error("one request failed:", err.message);
  }
}
loadAll();

Predict the output

QWhat does console.log(typeof null) print?+

"object" — a historical JavaScript bug kept forever for backwards compatibility.

QWhat does "5" + 3 print, and "5" - 3?+

+ prefers strings, so it prints "53". - has no string meaning, so it coerces to number and prints 2.

QIn what order do a, b, c, d appear in the log?+
event-loop.js
console.log("a");
setTimeout(() => console.log("b"), 0);
Promise.resolve().then(() => console.log("c"));
console.log("d");
// a d c b  — sync first, then microtask (c), then macrotask (b)