JavaScript 치트시트

ES6+ 최신 JavaScript 문법과 실전 패턴 모음 — 변수, 배열, 객체, 함수, 비동기, DOM, 유틸리티

📊

변수 & 타입

6 items

let / const

let은 재할당 가능, const는 불변 바인딩 (객체 내부는 변경 가능)

let count = 0;
count = 1; // OK

const API_URL = 'https://api.example.com';
// API_URL = '...'; // TypeError

const config = { debug: false };
config.debug = true; // OK — object mutation allowed
Tip: 기본적으로 const를 사용하고, 재할당이 필요한 경우에만 let을 사용하세요.

Template Literals

백틱(`)으로 문자열 보간 및 멀티라인 지원

const name = 'World';
const greeting = `Hello, ${name}!`;

// Tagged template
function highlight(strings, ...values) {
  return strings.reduce((acc, s, i) =>
    acc + s + (values[i] ? `<b>${values[i]}</b>` : ''), '');
}
const msg = highlight`Welcome ${name} today`;

typeof & Type Checking

런타임 타입 확인 방법

typeof 'hello'     // 'string'
typeof 42          // 'number'
typeof true        // 'boolean'
typeof undefined   // 'undefined'
typeof null        // 'object' (legacy bug)
typeof {}          // 'object'
typeof []          // 'object'
Array.isArray([])  // true — use this for arrays
Tip: typeof null === "object"는 JS 초기 버그입니다. null 체크는 === null을 사용하세요.

Nullish Coalescing (??)

null 또는 undefined일 때만 기본값 적용 (|| 과 다름)

const port = process.env.PORT ?? 3000;
// '' ?? 'default'  => ''     (empty string kept)
// '' || 'default'  => 'default' (falsy replaced)

// 0 ?? 42  => 0   (zero kept)
// 0 || 42  => 42  (zero replaced)

const user = response?.data ?? { name: 'Guest' };

Optional Chaining (?.)

중첩 객체의 안전한 접근 — null/undefined에서 단락 평가

const city = user?.address?.city;         // undefined if missing
const first = arr?.[0];                   // safe array access
const result = obj?.method?.();           // safe method call

// Combine with nullish coalescing
const name = user?.profile?.name ?? 'Anonymous';

Destructuring Assignment

객체/배열에서 값을 간결하게 추출

// Object destructuring with rename & default
const { name: userName, age = 25 } = user;

// Array destructuring — skip elements
const [first, , third] = [1, 2, 3];

// Swap variables
let a = 1, b = 2;
[a, b] = [b, a];

// Nested destructuring
const { address: { city } } = user;
Tip: 함수 매개변수에서도 구조 분해를 사용하면 가독성이 크게 향상됩니다.
📋

배열

7 items

map / filter / reduce

배열 변환, 필터링, 집계의 핵심 메서드

const nums = [1, 2, 3, 4, 5];

const doubled = nums.map(n => n * 2);
// [2, 4, 6, 8, 10]

const evens = nums.filter(n => n % 2 === 0);
// [2, 4]

const sum = nums.reduce((acc, n) => acc + n, 0);
// 15

// Chaining
const result = nums
  .filter(n => n > 2)
  .map(n => n * 10)
  .reduce((acc, n) => acc + n, 0); // 120

find / findIndex

조건을 만족하는 첫 번째 요소 또는 인덱스 반환

const users = [
  { id: 1, name: 'Alice' },
  { id: 2, name: 'Bob' },
  { id: 3, name: 'Charlie' },
];

const bob = users.find(u => u.name === 'Bob');
// { id: 2, name: 'Bob' }

const idx = users.findIndex(u => u.id === 3);
// 2 — returns -1 if not found

some / every

some: 하나라도 true면 true, every: 모두 true여야 true

const ages = [18, 25, 30, 15];

ages.some(a => a >= 21);  // true
ages.every(a => a >= 18); // false

// Practical: form validation
const fields = ['name', 'email', 'password'];
const allFilled = fields.every(f => form[f]?.length > 0);

flat / flatMap

중첩 배열 평탄화 및 매핑+평탄화 동시 수행

[[1, 2], [3, 4], [5]].flat();
// [1, 2, 3, 4, 5]

[1, [2, [3, [4]]]].flat(Infinity);
// [1, 2, 3, 4]

// flatMap = map + flat(1)
const sentences = ['hello world', 'foo bar'];
sentences.flatMap(s => s.split(' '));
// ['hello', 'world', 'foo', 'bar']

Spread & Rest ([...arr])

배열 복사, 병합, 나머지 요소 수집

// Shallow copy
const copy = [...original];

// Merge arrays
const all = [...arr1, ...arr2, newItem];

// Rest in destructuring
const [head, ...tail] = [1, 2, 3, 4];
// head = 1, tail = [2, 3, 4]

// Remove duplicates
const unique = [...new Set(arr)];
Tip: spread는 얕은 복사만 수행합니다. 깊은 복사는 structuredClone()을 사용하세요.

at() / Array.from()

at(): 음수 인덱스 지원, Array.from(): 이터러블을 배열로 변환

const arr = [10, 20, 30, 40, 50];
arr.at(-1);  // 50 — last element
arr.at(-2);  // 40

// Array.from with mapping
Array.from({ length: 5 }, (_, i) => i + 1);
// [1, 2, 3, 4, 5]

// Convert NodeList to Array
const divs = Array.from(document.querySelectorAll('div'));

// Array.from a Set
Array.from(new Set([1, 1, 2, 3])); // [1, 2, 3]

toSorted / toReversed / with

ES2023 불변 배열 메서드 — 원본 배열 유지

const nums = [3, 1, 4, 1, 5];

// Non-mutating sort
const sorted = nums.toSorted((a, b) => a - b);
// [1, 1, 3, 4, 5] — nums unchanged

// Non-mutating reverse
const reversed = nums.toReversed();
// [5, 1, 4, 1, 3]

// Replace at index (immutable)
const updated = nums.with(0, 99);
// [99, 1, 4, 1, 5]
Tip: React 상태 관리에서 불변 업데이트가 필요할 때 매우 유용합니다.
🗂️

객체

6 items

Object Destructuring

객체에서 필요한 속성만 추출, 이름 변경, 기본값 설정

const response = { data: [1, 2], status: 200, error: null };

const { data, status } = response;

// Rename + default
const { data: items, count = 0 } = response;

// Rest pattern
const { error, ...rest } = response;
// rest = { data: [1, 2], status: 200 }

Object.keys / values / entries

객체의 키, 값, [키, 값] 쌍을 배열로 변환

const config = { host: 'localhost', port: 3000, debug: true };

Object.keys(config);    // ['host', 'port', 'debug']
Object.values(config);  // ['localhost', 3000, true]
Object.entries(config); // [['host','localhost'], ...]

// Iterate with entries
for (const [key, value] of Object.entries(config)) {
  console.log(`${key}: ${value}`);
}

// entries → object
const obj = Object.fromEntries([['a', 1], ['b', 2]]);

Spread {...obj}

객체 복사, 병합, 속성 덮어쓰기

const defaults = { theme: 'dark', lang: 'en', debug: false };
const userPrefs = { lang: 'ko', debug: true };

// Merge (later wins)
const config = { ...defaults, ...userPrefs };
// { theme: 'dark', lang: 'ko', debug: true }

// Immutable update
const updated = { ...user, name: 'New Name' };

// Remove a property
const { password, ...safeUser } = user;
Tip: spread 병합에서 뒤에 오는 객체의 속성이 우선합니다.

Computed Property Names

대괄호로 동적 키를 가진 객체 생성

const field = 'email';
const obj = { [field]: 'test@example.com' };
// { email: 'test@example.com' }

// Dynamic state update (React pattern)
const handleChange = (e) => {
  setState(prev => ({
    ...prev,
    [e.target.name]: e.target.value,
  }));
};

structuredClone()

깊은 복사 — 중첩 객체, Map, Set, Date 모두 지원

const original = {
  name: 'Alice',
  scores: [90, 85, 92],
  meta: { created: new Date() },
};

const clone = structuredClone(original);
clone.scores.push(100);
// original.scores is still [90, 85, 92]
Tip: JSON.parse(JSON.stringify())보다 안전합니다. Date, Map, Set, ArrayBuffer를 올바르게 복사합니다.

Object.freeze / Object.assign

freeze: 변경 불가 객체, assign: 속성 복사

// Freeze — prevents mutation (shallow)
const ROUTES = Object.freeze({
  HOME: '/',
  ABOUT: '/about',
  API: '/api',
});
// ROUTES.HOME = '/new'; // silently fails (strict mode: TypeError)

// Object.assign — merge into target
const merged = Object.assign({}, defaults, overrides);

// Copy specific properties
const picked = Object.assign({}, { a: obj.a, b: obj.b });
🔧

함수

6 items

Arrow Functions

간결한 함수 문법 — this를 렉시컬로 바인딩

// Expression body (implicit return)
const double = x => x * 2;
const add = (a, b) => a + b;

// Block body (explicit return)
const greet = name => {
  const msg = `Hello, ${name}`;
  return msg;
};

// Return object literal (wrap in parens)
const makeUser = (name, age) => ({ name, age });

// In array methods
const names = users.map(u => u.name);
Tip: 화살표 함수는 자체 this가 없어 메서드 정의에는 부적합합니다. 일반 function을 사용하세요.

Default & Rest Parameters

매개변수 기본값 및 나머지 매개변수

// Default parameters
function createUser(name, role = 'viewer', active = true) {
  return { name, role, active };
}

// Rest parameters
function sum(...numbers) {
  return numbers.reduce((acc, n) => acc + n, 0);
}
sum(1, 2, 3, 4); // 10

// Combined
function log(level = 'info', ...messages) {
  console[level](...messages);
}

Closures

함수가 선언된 스코프의 변수를 기억하는 패턴

// Counter with private state
function createCounter(initial = 0) {
  let count = initial;
  return {
    increment: () => ++count,
    decrement: () => --count,
    getCount: () => count,
  };
}

const counter = createCounter(10);
counter.increment(); // 11
counter.increment(); // 12
counter.getCount();  // 12

Currying

다인자 함수를 단일 인자 함수 체인으로 변환

// Basic curry
const multiply = a => b => a * b;
const double = multiply(2);
const triple = multiply(3);

double(5);  // 10
triple(5);  // 15

// Practical: event handler factory
const handleChange = field => event => {
  setForm(prev => ({ ...prev, [field]: event.target.value }));
};
// <input onChange={handleChange('email')} />

Debounce

마지막 호출 후 지정 시간이 지나야 실행 (검색 입력 등)

function debounce(fn, delay = 300) {
  let timer;
  return (...args) => {
    clearTimeout(timer);
    timer = setTimeout(() => fn(...args), delay);
  };
}

// Usage
const search = debounce(query => {
  fetch(`/api/search?q=${query}`);
}, 500);

input.addEventListener('input', e => search(e.target.value));
Tip: 검색 입력, 윈도우 리사이즈 등 빈번한 이벤트에 필수적인 패턴입니다.

Throttle

지정 시간 간격마다 최대 1회 실행 (스크롤 등)

function throttle(fn, limit = 300) {
  let inThrottle = false;
  return (...args) => {
    if (!inThrottle) {
      fn(...args);
      inThrottle = true;
      setTimeout(() => (inThrottle = false), limit);
    }
  };
}

// Usage
window.addEventListener('scroll',
  throttle(() => console.log(window.scrollY), 200)
);

비동기

6 items

async / await

프로미스를 동기 코드처럼 작성하는 문법

async function fetchUser(id) {
  try {
    const res = await fetch(`/api/users/${id}`);
    if (!res.ok) throw new Error(`HTTP ${res.status}`);
    const user = await res.json();
    return user;
  } catch (err) {
    console.error('Failed to fetch user:', err);
    return null;
  }
}

// Arrow async
const getUsers = async () => {
  const res = await fetch('/api/users');
  return res.json();
};

Promise.all

여러 프로미스를 동시에 실행, 하나라도 실패하면 전체 실패

const [users, posts, comments] = await Promise.all([
  fetch('/api/users').then(r => r.json()),
  fetch('/api/posts').then(r => r.json()),
  fetch('/api/comments').then(r => r.json()),
]);

// With error handling
try {
  const results = await Promise.all(urls.map(u => fetch(u)));
} catch (err) {
  console.error('One request failed:', err);
}
Tip: 독립적인 요청은 순차 await 대신 Promise.all로 병렬 실행하면 성능이 크게 향상됩니다.

Promise.allSettled

모든 프로미스 완료 대기 — 일부 실패해도 계속 진행

const results = await Promise.allSettled([
  fetch('/api/a'),
  fetch('/api/b'),
  fetch('/api/c'), // may fail
]);

const successful = results
  .filter(r => r.status === 'fulfilled')
  .map(r => r.value);

const failed = results
  .filter(r => r.status === 'rejected')
  .map(r => r.reason);

AbortController

진행 중인 fetch 요청을 취소 (타임아웃, 컴포넌트 언마운트)

// Timeout pattern
async function fetchWithTimeout(url, ms = 5000) {
  const controller = new AbortController();
  const timeout = setTimeout(() => controller.abort(), ms);

  try {
    const res = await fetch(url, { signal: controller.signal });
    return await res.json();
  } finally {
    clearTimeout(timeout);
  }
}

// React cleanup
useEffect(() => {
  const controller = new AbortController();
  fetch('/api/data', { signal: controller.signal })
    .then(r => r.json())
    .then(setData);
  return () => controller.abort();
}, []);
Tip: React useEffect에서 fetch 사용 시 반드시 AbortController로 정리하세요.

Promise.race / Promise.any

race: 첫 번째 완료된 것 반환, any: 첫 번째 성공한 것 반환

// Race — first to settle wins (resolve or reject)
const result = await Promise.race([
  fetch('/api/primary'),
  new Promise((_, reject) =>
    setTimeout(() => reject(new Error('timeout')), 3000)
  ),
]);

// Any — first to resolve wins (ignores rejections)
const fastest = await Promise.any([
  fetch('https://cdn1.example.com/data'),
  fetch('https://cdn2.example.com/data'),
  fetch('https://cdn3.example.com/data'),
]);

for await...of

비동기 이터러블을 순차적으로 처리

// Stream processing
async function* fetchPages(url) {
  let page = 1;
  while (true) {
    const res = await fetch(`${url}?page=${page}`);
    const data = await res.json();
    if (data.length === 0) break;
    yield data;
    page++;
  }
}

for await (const page of fetchPages('/api/items')) {
  console.log(`Got ${page.length} items`);
}
🖥️

DOM

6 items

querySelector / querySelectorAll

CSS 선택자로 DOM 요소 검색

// Single element
const btn = document.querySelector('#submit-btn');
const first = document.querySelector('.card');

// All matching elements (NodeList)
const cards = document.querySelectorAll('.card');
cards.forEach(card => card.classList.add('active'));

// Scoped query
const form = document.querySelector('form');
const inputs = form.querySelectorAll('input[required]');

addEventListener

이벤트 리스너 등록 및 옵션 활용

// Basic
btn.addEventListener('click', () => { /* ... */ });

// With options
el.addEventListener('scroll', handler, { passive: true });
el.addEventListener('click', handler, { once: true });

// Remove listener
const handler = () => console.log('clicked');
btn.addEventListener('click', handler);
btn.removeEventListener('click', handler);
Tip: passive: true는 스크롤 성능을 향상시킵니다. once: true는 자동으로 리스너를 제거합니다.

Event Delegation

부모 요소에서 자식 이벤트를 처리하는 패턴

// Instead of adding listeners to each button...
document.querySelector('.toolbar').addEventListener('click', e => {
  const btn = e.target.closest('button[data-action]');
  if (!btn) return;

  switch (btn.dataset.action) {
    case 'save': handleSave(); break;
    case 'delete': handleDelete(); break;
    case 'share': handleShare(); break;
  }
});
Tip: 동적으로 추가되는 요소에도 작동하며 메모리 사용량이 적습니다.

classList

CSS 클래스 추가, 제거, 토글, 확인

el.classList.add('active', 'highlight');
el.classList.remove('hidden');
el.classList.toggle('dark-mode');
el.classList.contains('active'); // true/false

// Replace one class with another
el.classList.replace('old-class', 'new-class');

// Conditional toggle
el.classList.toggle('visible', isLoggedIn);

dataset (data-* attributes)

HTML data-* 속성 읽기/쓰기

// HTML: <div data-user-id="42" data-role="admin">
const el = document.querySelector('[data-user-id]');

el.dataset.userId;  // '42' (camelCase)
el.dataset.role;    // 'admin'

// Set data attribute
el.dataset.active = 'true';
// Result: <div ... data-active="true">

// Remove
delete el.dataset.active;

createElement & Fragment

DOM 요소 프로그래밍 방식으로 생성

// Create single element
const card = document.createElement('div');
card.className = 'card';
card.textContent = 'Hello';
container.appendChild(card);

// DocumentFragment for batch inserts (better perf)
const fragment = document.createDocumentFragment();
items.forEach(item => {
  const li = document.createElement('li');
  li.textContent = item.name;
  fragment.appendChild(li);
});
list.appendChild(fragment); // single DOM update
Tip: DocumentFragment를 사용하면 DOM 업데이트를 한 번만 수행하여 성능이 향상됩니다.

ES6+ 기능

6 items

Set & Map

Set: 고유 값 컬렉션, Map: 모든 타입의 키-값 저장소

// Set — unique values
const unique = new Set([1, 2, 2, 3, 3]);
unique.add(4);
unique.has(2);   // true
unique.delete(1);
unique.size;     // 3

// Map — any key type
const cache = new Map();
cache.set(userObj, { lastSeen: Date.now() });
cache.get(userObj);
cache.has(userObj); // true

// Convert
[...unique];              // Set → Array
Object.fromEntries(map);  // Map → Object
Tip: Set은 배열 중복 제거에, Map은 객체를 키로 사용해야 할 때 최적입니다.

WeakMap & WeakRef

가비지 컬렉션을 방해하지 않는 참조

// WeakMap — keys are weakly held (GC-friendly)
const metadata = new WeakMap();
function track(element) {
  metadata.set(element, { clicks: 0 });
}
// When element is removed from DOM, entry is auto-cleaned

// WeakRef — weak reference to an object
let target = { data: 'important' };
const ref = new WeakRef(target);

// Later: may return undefined if GC'd
const obj = ref.deref();
if (obj) console.log(obj.data);

Symbol

고유하고 변경 불가능한 값 — 메타 속성, 프로토콜 정의에 사용

// Unique property keys
const ID = Symbol('id');
const user = { [ID]: 42, name: 'Alice' };
user[ID]; // 42

// Well-known symbols
class Range {
  constructor(start, end) { this.start = start; this.end = end; }
  *[Symbol.iterator]() {
    for (let i = this.start; i <= this.end; i++) yield i;
  }
}
[...new Range(1, 5)]; // [1, 2, 3, 4, 5]

Proxy

객체 동작을 가로채서 커스터마이징하는 메타프로그래밍 도구

// Validation proxy
const validator = new Proxy({}, {
  set(target, prop, value) {
    if (prop === 'age' && (typeof value !== 'number' || value < 0)) {
      throw new TypeError('Age must be a positive number');
    }
    target[prop] = value;
    return true;
  },
  get(target, prop) {
    return prop in target ? target[prop] : `No such property: ${prop}`;
  },
});

validator.age = 25;  // OK
// validator.age = -5; // TypeError

Generators

실행을 일시 중지하고 값을 순차적으로 생성하는 함수

function* fibonacci() {
  let [a, b] = [0, 1];
  while (true) {
    yield a;
    [a, b] = [b, a + b];
  }
}

const fib = fibonacci();
fib.next().value; // 0
fib.next().value; // 1
fib.next().value; // 1
fib.next().value; // 2

// Take first N
function* take(iter, n) {
  let i = 0;
  for (const val of iter) {
    if (i++ >= n) break;
    yield val;
  }
}
[...take(fibonacci(), 8)]; // [0, 1, 1, 2, 3, 5, 8, 13]

Intl API

내장 국제화 — 날짜, 숫자, 통화 포맷팅

// Number formatting
new Intl.NumberFormat('en-US', {
  style: 'currency', currency: 'USD',
}).format(1234.5); // '$1,234.50'

// Date formatting
new Intl.DateTimeFormat('ko-KR', {
  year: 'numeric', month: 'long', day: 'numeric',
}).format(new Date()); // '2026년 4월 13일'

// Relative time
new Intl.RelativeTimeFormat('en', { numeric: 'auto' })
  .format(-1, 'day'); // 'yesterday'
🛠️

유틸리티 패턴

6 items

Deep Clone

객체의 완전한 깊은 복사

// Modern (recommended)
const clone = structuredClone(original);

// JSON method (no functions, Date becomes string)
const clone2 = JSON.parse(JSON.stringify(original));

// Recursive (handles most cases)
function deepClone(obj) {
  if (obj === null || typeof obj !== 'object') return obj;
  if (obj instanceof Date) return new Date(obj);
  if (obj instanceof Map) return new Map([...obj].map(([k,v]) => [k, deepClone(v)]));
  const copy = Array.isArray(obj) ? [] : {};
  for (const key of Object.keys(obj)) copy[key] = deepClone(obj[key]);
  return copy;
}

Memoize

함수 호출 결과를 캐싱하여 반복 계산 방지

function memoize(fn) {
  const cache = new Map();
  return (...args) => {
    const key = JSON.stringify(args);
    if (cache.has(key)) return cache.get(key);
    const result = fn(...args);
    cache.set(key, result);
    return result;
  };
}

// Usage
const expensiveCalc = memoize((n) => {
  console.log('computing...');
  return n * n;
});

expensiveCalc(5); // computing... 25
expensiveCalc(5); // 25 (cached, no log)

Pipe / Compose

함수를 체인으로 연결하여 데이터를 변환하는 패턴

// Pipe: left to right
const pipe = (...fns) => x => fns.reduce((acc, fn) => fn(acc), x);

// Compose: right to left
const compose = (...fns) => x => fns.reduceRight((acc, fn) => fn(acc), x);

const processUser = pipe(
  name => name.trim(),
  name => name.toLowerCase(),
  name => name.replace(/\s+/g, '-'),
  name => `@${name}`,
);

processUser('  John Doe  '); // '@john-doe'
Tip: TC39 파이프 연산자(|>) 제안이 진행 중이지만, 현재는 pipe 함수로 동일한 패턴을 구현합니다.

Event Emitter

발행-구독(pub/sub) 이벤트 패턴

class EventEmitter {
  #listeners = new Map();

  on(event, handler) {
    if (!this.#listeners.has(event)) this.#listeners.set(event, new Set());
    this.#listeners.get(event).add(handler);
    return () => this.off(event, handler); // unsubscribe fn
  }

  off(event, handler) {
    this.#listeners.get(event)?.delete(handler);
  }

  emit(event, ...args) {
    this.#listeners.get(event)?.forEach(h => h(...args));
  }
}

const bus = new EventEmitter();
const unsub = bus.on('save', data => console.log(data));
bus.emit('save', { id: 1 }); // logs { id: 1 }
unsub(); // unsubscribe

UUID Generation

고유 식별자 생성 (crypto API 기반)

// Modern — built-in (Chrome 92+, Node 19+)
const id = crypto.randomUUID();
// 'f47ac10b-58cc-4372-a567-0e02b2c3d479'

// Fallback — manual v4 UUID
function uuidv4() {
  return '10000000-1000-4000-8000-100000000000'
    .replace(/[018]/g, c =>
      (+c ^ crypto.getRandomValues(new Uint8Array(1))[0] & 15 >> +c / 4)
        .toString(16));
}

// NanoID-style short ID
const nanoid = (len = 21) =>
  crypto.getRandomValues(new Uint8Array(len))
    .reduce((s, b) => s + (b & 63).toString(36), '').slice(0, len);

Sleep / Delay

지정 시간 동안 실행을 일시 중지하는 유틸리티

const sleep = ms => new Promise(resolve => setTimeout(resolve, ms));

// Usage with async/await
async function fetchWithRetry(url, retries = 3) {
  for (let i = 0; i < retries; i++) {
    try {
      return await fetch(url);
    } catch (err) {
      if (i === retries - 1) throw err;
      await sleep(1000 * 2 ** i); // exponential backoff
    }
  }
}
Tip: 지수 백오프(exponential backoff)는 재시도 간격을 점진적으로 늘려 서버 부하를 줄입니다.

JavaScript 치트시트 사용 가이드

ES6+ 이후 JavaScript는 매년 새로운 기능이 추가되고 있습니다. 이 치트시트는 실무에서 가장 자주 사용하는 최신 문법과 패턴을 한 곳에 정리하여 빠르게 참고할 수 있도록 만들었습니다.

왜 최신 JavaScript 문법을 배워야 하나요?

ES6(2015) 이후 도입된 화살표 함수, 구조 분해, 옵셔널 체이닝, nullish coalescing 등의 문법은 코드를 더 간결하고 안전하게 만들어 줍니다. React, Vue, Next.js 등 모든 현대 프레임워크가 이러한 문법을 기반으로 설계되어 있어, 최신 JavaScript를 익히는 것은 프론트엔드 개발의 필수 요건입니다.

비동기 프로그래밍 마스터하기

JavaScript의 비동기 모델은 콜백에서 Promise, 그리고 async/await로 발전해 왔습니다. Promise.all, Promise.allSettled, AbortController 등을 활용하면 복잡한 비동기 흐름도 깔끔하게 관리할 수 있습니다. 이 치트시트의 비동기 섹션에서 실전 패턴을 확인하세요.

실전에서 바로 쓰는 유틸리티

debounce, throttle, memoize, deep clone 등의 유틸리티 패턴은 프로젝트 규모에 관계없이 항상 필요합니다. lodash 같은 라이브러리 없이도 순수 JavaScript로 구현할 수 있으며, 이 치트시트에서 복사하여 바로 사용할 수 있습니다.

FAQ

Related Tools

Also Used Together