ES6+, closures, promises, async/await, DOM, modules & event loop
Language// Variables
let x = 10; // block-scoped, reassignable
const y = 20; // block-scoped, constant
var z = 30; // function-scoped (avoid)
// Types: string, number, boolean, null, undefined, symbol, bigint, object
typeof "hello" // "string"
typeof 42 // "number"
typeof null // "object" (JS quirk!)
// Template literals
const name = "Alice";
const msg = `Hello ${name}, ${2 + 3} items`;
// Destructuring
const [a, b, ...rest] = [1, 2, 3, 4]; // a=1, b=2, rest=[3,4]
const { name: n, age = 25 } = person; // rename + default
// Spread
const arr2 = [...arr1, 4, 5];
const obj2 = { ...obj1, key: "val" };
// Optional chaining & nullish coalescing
user?.address?.city // undefined if any null
value ?? "default" // only for null/undefined// Arrow functions
const add = (a, b) => a + b;
const square = x => x * x;
const greet = () => "Hello";
// Default params, rest params
function log(msg, level = "info") { }
function sum(...nums) { return nums.reduce((a,b) => a+b, 0); }
// Closure
function counter() {
let count = 0;
return {
inc: () => ++count,
get: () => count
};
}
const c = counter();
c.inc(); c.inc(); c.get(); // 2
// Higher-order
const pipe = (...fns) => x => fns.reduce((v, f) => f(v), x);
// this binding
// Arrow functions inherit 'this' from enclosing scope
// Regular functions: 'this' depends on how calledconst arr = [1, 2, 3, 4, 5];
// Transform (immutable)
arr.map(x => x * 2) // [2,4,6,8,10]
arr.filter(x => x > 3) // [4,5]
arr.reduce((sum, x) => sum + x, 0) // 15
arr.flatMap(x => [x, x*2]) // [1,2,2,4,3,6...]
// Search
arr.find(x => x > 3) // 4
arr.findIndex(x => x > 3) // 3
arr.includes(3) // true
arr.some(x => x > 4) // true
arr.every(x => x > 0) // true
arr.indexOf(3) // 2
// Mutating
arr.push(6); arr.pop(); // end
arr.unshift(0); arr.shift(); // start
arr.splice(1, 2); // remove 2 items at index 1
arr.sort((a,b) => a - b); // numeric sort
arr.reverse();
// Other
arr.slice(1, 3) // [2,3] (no mutation)
arr.concat([6,7]) // merge arrays
arr.join(", ") // "1, 2, 3, 4, 5"
Array.from({length:5}, (_,i) => i) // [0,1,2,3,4]
[...new Set(arr)] // unique values// Promise
const p = new Promise((resolve, reject) => {
setTimeout(() => resolve("done"), 1000);
});
p.then(val => console.log(val))
.catch(err => console.error(err))
.finally(() => console.log("cleanup"));
// Async/Await
async function fetchData(url) {
try {
const res = await fetch(url);
const data = await res.json();
return data;
} catch (err) {
console.error(err);
}
}
// Parallel execution
const [users, posts] = await Promise.all([
fetch("/users").then(r => r.json()),
fetch("/posts").then(r => r.json()),
]);
Promise.race([p1, p2]) // first to settle
Promise.allSettled([p1, p2]) // wait for all, no short-circuit
Promise.any([p1, p2]) // first to fulfill// Object shorthand
const name = "Alice";
const obj = { name, greet() { return `Hi ${this.name}`; } };
// Computed property
const key = "color";
const obj2 = { [key]: "red" };
// Object methods
Object.keys(obj) Object.values(obj) Object.entries(obj)
Object.assign({}, obj, { age: 30 }) // shallow merge
Object.freeze(obj) Object.seal(obj)
// Classes
class Animal {
#name; // private field
constructor(name) { this.#name = name; }
get name() { return this.#name; }
speak() { return `${this.#name} makes a sound`; }
static create(name) { return new Animal(name); }
}
class Dog extends Animal {
constructor(name, breed) {
super(name);
this.breed = breed;
}
speak() { return `${this.name} barks`; }
}// Selectors
document.getElementById("id")
document.querySelector(".class")
document.querySelectorAll("div.item")
// Manipulation
el.textContent = "Hello";
el.innerHTML = "<b>Bold</b>";
el.setAttribute("class", "active");
el.classList.add("show"); el.classList.toggle("open");
el.style.color = "red";
el.dataset.id // data-id attribute
// Create & insert
const div = document.createElement("div");
div.textContent = "New";
parent.appendChild(div);
parent.insertBefore(div, ref);
el.remove();
// Events
el.addEventListener("click", (e) => {
e.preventDefault();
e.stopPropagation();
e.target // clicked element
e.currentTarget // element with listener
});
// Event delegation
document.querySelector("ul").addEventListener("click", (e) => {
if (e.target.matches("li")) handleClick(e.target);
});// ES Modules
export const PI = 3.14;
export default function add(a, b) { return a + b; }
export { add, PI };
import add from './math.js';
import { PI, add } from './math.js';
import * as math from './math.js';
// Dynamic import
const module = await import('./heavy.js');
// Map, Set, WeakMap, WeakRef
const map = new Map([["a", 1], ["b", 2]]);
map.set("c", 3); map.get("a"); map.has("b"); map.size;
const set = new Set([1,2,3,1]); // {1,2,3}
set.add(4); set.has(1); set.delete(2);
// Proxy
const handler = {
get(target, key) { return key in target ? target[key] : 0; }
};
const proxy = new Proxy({}, handler);