JavaScript 가이드

언어 내부, 런타임, 프레임워크 — 코드 레벨로 동작 원리 정리

⚙️ 언어 내부

🔄

이벤트 루프 — setTimeout(fn, 0)이 즉시 실행되지 않는 이유

Call Stack, Task Queue, Microtask Queue의 실행 순서

JavaScript는 싱글 스레드인데 비동기가 되는 이유: 이벤트 루프가 Call Stack이 비었을 때 Task Queue에서 콜백을 꺼내서 실행하기 때문. Promise의 then은 Microtask Queue에 들어가서 일반 Task보다 먼저 실행된다.

🔗

클로저와 스코프 체인 — 함수가 외부 변수를 기억하는 원리

Lexical Environment 객체가 만드는 스코프 체인의 내부 구조

클로저는 함수가 생성된 시점의 Lexical Environment를 캡처해서 보존하는 것이다. 함수가 외부 스코프의 변수를 참조하면, 그 Lexical Environment 객체가 가비지 컬렉션되지 않고 살아남는다.

🧬

프로토타입 체인 — class가 없던 시절의 상속

__proto__, prototype, Object.create()의 관계

JavaScript의 class는 문법적 설탕이다. 내부적으로 프로토타입 체인으로 동작한다. 객체의 __proto__가 부모 객체를 가리키고, 프로퍼티를 못 찾으면 체인을 따라 올라간다.

⛓️

Promise 내부 — then()이 Microtask Queue에 들어가는 과정

Promise의 3가지 상태와 thenable 체이닝의 실행 메커니즘

Promise는 pending/fulfilled/rejected 3가지 상태를 가진 상태 머신이다. resolve() 호출 시 then에 등록된 콜백이 Microtask Queue에 들어간다. async/await는 이 Promise의 문법적 설탕.

🌐 브라우저 API

👷

Web Workers — JavaScript에서 멀티스레드를 쓰는 법

postMessage의 구조화된 복제(Structured Clone)와 SharedArrayBuffer

Web Worker는 메인 스레드와 별도의 스레드에서 JavaScript를 실행한다. DOM 접근 불가, postMessage로 통신. 무거운 계산을 Worker에 넘기면 UI가 안 멈춘다.

Service Worker 생명주기 — install, activate, fetch의 순서

PWA의 핵심, 오프라인 캐시가 동작하는 메커니즘

Service Worker는 브라우저와 네트워크 사이에 프록시로 동작한다. install → activate → fetch 순서로 생명주기가 진행되며, Cache API로 리소스를 저장해서 오프라인에서도 앱이 작동하게 만든다.

👁️

Intersection Observer — 스크롤 이벤트 없이 요소 가시성 감지

lazy loading, 무한 스크롤, 애니메이션 트리거의 성능 좋은 구현 방법

Intersection Observer는 요소가 뷰포트에 들어오거나 나갈 때 콜백을 실행한다. scroll 이벤트 + getBoundingClientRect()보다 성능이 좋고, 브라우저가 최적화된 타이밍에 실행해준다.

💬

Popover API — JavaScript 없이 툴팁을 만들 수 있게 된 이유

popover 속성 하나로 열기/닫기, Esc 처리, 접근성이 자동으로 동작하는 브라우저 네이티브 UI

기존 툴팁은 이벤트 리스너, 상태 관리, ARIA 속성 수동 동기화가 전부 필요했다. Popover API는 이걸 브라우저 네이티브로 대체한다. popover 속성과 popovertarget만으로 열기/닫기, Esc 키, 키보드 내비게이션이 자동 동작한다.