DEV Community

Cover image for 5 JavaScript concepts I kept forgetting (so I made them my lock screen)
Techcookies for TechCookies

Posted on

5 JavaScript concepts I kept forgetting (so I made them my lock screen)

I used to "learn" the same JavaScript concepts every few months. I'd read about the event loop, nod along, and a month later get a predict-the-output question wrong in an interview.

What finally worked was seeing the rule every day. I turned each concept into a phone wallpaper with a short why at the bottom, so every time I unlock my phone, I revise one thing.

Here are the five that helped most. Try to predict each output before reading the answer.


1. The event loop: why promises beat setTimeout

setTimeout(() => console.log('C'));
Promise.resolve().then(() => console.log('B'));
console.log('A');
Enter fullscreen mode Exit fullscreen mode

Output: A, B, C

The rule that made it stick:

  1. Run all synchronous code on the call stack.
  2. When the stack is empty, drain every microtask (promise callbacks, code after await, queueMicrotask).
  3. Then take one macrotask (setTimeout, I/O, clicks) and repeat.

So a promise callback always runs before setTimeout(fn, 0), even though both look "async". The 0 doesn't mean "now"; it means "next macrotask".


2. Closures: functions remember where they were born

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

const next = counter();
next();
next();
console.log(next());
Enter fullscreen mode Exit fullscreen mode

Output: 3

The returned function keeps a live reference to count, not a copy. That's a closure: a function plus the variables that were in scope when it was created.

The classic interview trap is the same idea:

for (var i = 0; i < 3; i++) {
  setTimeout(() => console.log(i));
}
// 3, 3, 3
Enter fullscreen mode Exit fullscreen mode

All three callbacks close over the same var i, which is 3 by the time they run. Change var to let and you get 0, 1, 2, because let creates a new binding for each loop iteration.


3. this: ask how the function was called

const user = {
  name: 'Asha',
  greet() { return `Hi, ${this.name}`; },
};

const greet = user.greet;
console.log(greet());
Enter fullscreen mode Exit fullscreen mode

Output: in an ES module or strict mode, TypeError: Cannot read properties of undefined (reading 'name'). In an old-style non-strict script, this falls back to the global object, so you get a wrong name instead of an error. Either way, it's not Hi, Asha.

this isn't decided where a function is written; it's decided by how it's called. Check these in order:

  • Arrow function: never gets its own this; uses the one from the surrounding code.
  • new Fn(): this is the brand-new object.
  • fn.call(obj) / apply / bind: this is obj.
  • obj.fn(): this is whatever is left of the dot.
  • Plain fn(): undefined in strict mode.

greet() has no dot at call time, so it lost user.


4. Type coercion: + and - play by different rules

Cover the answers and predict:

[] + {}        // ?
"5" - 2        // ?
"5" + 2        // ?
null == 0      // ?
null >= 0      // ?
Enter fullscreen mode Exit fullscreen mode

Answers: "[object Object]", 3, "52", false, true

  • + switches to string concatenation if either side ends up a string. [] becomes "" and {} becomes "[object Object]".
  • - has no string version, so it always converts to numbers.
  • null >= 0 converts null to 0, so 0 >= 0 is true. But == has a special rule: null only equals undefined. That's how null can be >= 0 without being == 0.

5. Hoisting: let is hoisted too, just locked

console.log(a); // ?
var a = 1;

console.log(b); // ?
let b = 2;
Enter fullscreen mode Exit fullscreen mode

Output: undefined, then ReferenceError: Cannot access 'b' before initialization

Both declarations are hoisted. The difference:

  • var is hoisted and initialized to undefined.
  • let, const and class are hoisted but sit in the temporal dead zone until their line runs.
  • Function declarations are hoisted completely, so you can call them before they appear.

The error is a feature: it catches bugs that var would silently hide as undefined.


Want them on your lock screen?

I run TechCookies, a small platform built around this "predict first, then learn the why" style. These wallpapers came out of it, and there are 26 in total: JavaScript, TypeScript, SQL, DSA, system design, Java and Python.

πŸ‘‰ Get the full wallpaper pack

Tip for iPhone: put them in one album and use Photo Shuffle on the lock screen, so you get a new concept every day.

Which JavaScript concept took you the longest to really understand? I'm making more wallpapers and would like to cover the ones people actually struggle with.

Top comments (0)