image

JavaScript

7 January 2026


let and var in for loop

for (var i = 1; i <= 5; i++) {
  setTimeout(function() {
    console.log(i); // This function forms a closure
  }, i * 1000);
}
// Output: 6, 6, 6, 6, 6 (printed after 1, 2, 3, 4, 5 seconds)
 
for (let i = 1; i <= 5; i++) {
  setTimeout(function() {
    console.log(i); // This function forms a closure
  }, i * 1000);
}
// Output: 1, 2, 3, 4, 5 (printed sequentially after 1, 2, 3, 4, 5 seconds)
 

Revealing module pattern

Turn this object litera into a module that only exposes specific methods

let myModule = (() => {
  const _data = []
 
  const _add = () => {}
  const _remove = () => {}
 
  return {
    add: _add,
    remove: _remove
  }
  
})()
// Immediately Invoked Function Expression (IIFE)

ASI

Automatic Semicolon Insertion

let obj = {a:123}
[obj].forEach() // Cannot access 'obj' before initialization
 
let obj = { a: 123 }
[obj].forEach(a => console.log(a)); // {a: 123}

Single pattern

const SingletonClassic = (function () {
  let instance;
 
  function createInstance() {
    let isRunning = false;
 
    const start = () => (isRunning = true);
    const stop = () => (isRunning = false);
    const status = () => console.log(isRunning);
 
    return { start, stop, status };
  }
 
  instance = createInstance();
 
  return {
    getInstance () {
      return instance;
    },
  };
})();
 
const instanceA = SingletonClassic.getInstance();
const instanceB = SingletonClassic.getInstance();
 
instanceA.status() // false
instanceB.status() // false
 
instanceB.start()
 
instanceA.status() // true
instanceB.status() // true
 

Closure

function f1() {
  for (var i = 0; i < 3; i++) {
    setTimeout(() => console.log(i), 1000 * i); // 3 3 3
  }
 
  // i still access there
}
 
function f2() {
  for (let i = 0; i < 3; i++) {
    setTimeout(() => console.log(i), 1000 * i); // 0 1 2
  }
 
  // can;t access i there
}
 
// Using bind
function f3() {
  for (var i = 0; i < 3; i++) {
    setTimeout(((x) => console.log(x)).bind(null, i), 1000 * i); // 0 1 2
  }
}
 
 
// Using IIFE
function f4() {
  for (var i = 0; i < 3; i++) {
    setTimeout(
      (
        (x) => () => console.log(x) // 0 1 2
      )(i),
      1000 * i,
    );
  }
}
 

Pre-populated array

[...Array(5)].map(() => Math.random())
[...Array(5).keys()] // 0 1 2 3 4 5

Hoist

var it's hoisted and assigned undefined as default value

let is's hoisted but has no default value

Random hex color

let n = Math.random()
n = n.toStrig(16) // (hex, 0-9 a-f) => 0.f23be3234ae

ParseInt

// default parseInt radix is 10
// map((v, i, arr) => {})
 
let n = ['1', '7', '11'].map(n => parseInt(n)) // [1, NaN, 3]

This keyword

Arrow function is lexical scope

const obj = {
  a: "object value",
  foo: () => {
    console.log(this); // {}
  },
  bar: function() {
    console.log(this); // {a: "object value"}
  }
};

Check num is integer

!isNaN(num) && parseInt(num) === num

Array index

const arr = [1];
arr[3] = 5;
 
for (var i = 0; i < arr.length; i++) {
  console.log(arr[i]); // 1 undefined undefined 5
}
 
arr.forEach((v) => console.log(v)); // 1 5

Make withby Nguyen Huu Dat

© 2025