Variables & Scoping
| Keyword |
Scope |
Reassign |
Hoisting |
| const | Block | No | TDZ |
| let | Block | Yes | TDZ |
| var | Function | Yes | undefined |
console.log(a); var a = 1; // undefined (hoisted)
console.log(b); let b = 2; // ReferenceError (TDZ)
const obj = {}; obj.x = 1; // ok — binding const, value mutable
Closures & this
Closure Factory
function counter() {
let n = 0;
return () => ++n; // closes over n
}
const next = counter();
next(); // 1 next(); // 2
this Binding
// arrow: lexical this (inherits from scope)
const o = { v: 1, get() { return (() => this.v)(); } };
fn.call(ctx, a, b); // invoke with this = ctx
fn.apply(ctx, [a, b]); // args as array
const bound = fn.bind(ctx); // returns bound copy
Destructuring & Spread
const { name, role = 'user' } = obj; // default
const { a: alias } = obj; // rename
const [first, ...rest] = arr; // array rest
const { id, ...others } = obj; // object rest
[x, y] = [y, x]; // swap
const clone = { ...obj, extra: 1 }; // spread merge
const joined = [...a, ...b]; // spread arrays
f(...args); // spread call
Array Methods
| Method | Returns | Use |
| map | new array | transform each |
| filter | new array | keep matches |
| reduce | single value | fold / accumulate |
| find | element | first match |
| some / every | boolean | any / all match |
| flatMap | new array | map + flatten 1 |
arr.filter(x => x.paid)
.map(x => x.total)
.reduce((s, n) => s + n, 0);
Async & Promises
async function f() {
try {
const r = await fetch(url);
if (!r.ok) throw new Error(r.status);
return await r.json();
} catch (e) { /* handle */ }
}
await Promise.all([a, b]); // all fulfil, else reject
await Promise.allSettled([a, b]); // never rejects
await Promise.race([a, b]); // first settled
await Promise.any([a, b]); // first fulfilled
Event Loop Order
// sync -> ALL microtasks -> one macrotask -> repeat
console.log('1'); // sync
setTimeout(() => console.log('4'), 0); // macrotask
Promise.resolve().then(() => log('3')); // microtask
console.log('2'); // sync -> 1 2 3 4
ES Modules
export const x = 1; // named
export default function () {} // default
export { a, b as c }; // list + rename
import def, { a, b } from './m.js';
import * as ns from './m.js'; // namespace
const m = await import('./m.js'); // dynamic (code splitting)
TypeScript Types
interface vs type
interface User { id: number; name: string; role?: 'a' | 'm'; }
interface Admin extends User { perms: string[]; }
type Status = 'idle' | 'ok' | 'error'; // union
type Point = [number, number]; // tuple
type WithMeta = User & { meta: string }; // intersection
// interface = merges/extends; type = unions/tuples/computed
Generics
function first<T>(a: Array<T>): T | undefined { return a[0]; }
function len<T extends { length: number }>(x: T) { return x.length; }
type Box<T> = { value: T };
Utility Types
| Type | Effect |
| Partial<T> | all props optional |
| Required<T> | all props required |
| Readonly<T> | all props readonly |
| Pick<T,K> | keep keys K |
| Omit<T,K> | drop keys K |
| Record<K,V> | key/value map |
| ReturnType<F> | function return type |
Narrowing
if (typeof x === 'string') { /* x: string */ }
if ('role' in obj) { /* has role */ }
if (e instanceof Error) { /* e: Error */ }
if (r.ok) r.data; else r.error; // discriminated union
tsconfig strict
{
"compilerOptions": {
"strict": true, // enables the whole family
"noUncheckedIndexedAccess": true,
"noImplicitAny": true, // (part of strict)
"strictNullChecks": true // (part of strict)
}
}