JavaScript 심화
Rest/Spread·클로저·타이머: ‘상태’와 ‘시간’을 다루는 감각
문법(… )을 올바르게 구분하고, 클로저와 이벤트 루프 관점에서 타이머를 이해합니다.
그림 1. 분해/모으기/펼치기 치트시트
그림 2. 타이머와 이벤트 루프(큰 그림)
Rest / Spread: 헷갈리는 이유부터 정리해보기
Rest와 Spread는 둘 다 점 세 개(...)를 사용하지만, 쓰이는 위치가 다릅니다.
- Rest: “남은 값을 모으는” 문법 (함수 매개변수, 구조 분해 패턴에서 사용)
- Spread: “값을 펼치는” 문법 (배열/객체 리터럴, 함수 호출에서 사용)
function logAll(first, ...rest) { // Rest
console.log(first, rest);
}
const arr = [1,2,3];
console.log(...arr); // Spread
주의
Spread로 만든 복사는 얕은 복사입니다. 중첩 객체가 있으면 내부 참조는 그대로 공유됩니다.
Spread로 만든 복사는 얕은 복사입니다. 중첩 객체가 있으면 내부 참조는 그대로 공유됩니다.
Closure: ‘함수 + 외부 상태’가 묶이는 현상
클로저는 “함수가 만들어질 때의 외부 변수 환경을 기억하는 것”으로 이해하시면 가장 편합니다. 실무에서는 캡슐화, 상태 유지, 팩토리 함수 등에서 자연스럽게 등장합니다.
function makeCounter() {
let n = 0;
return function () {
n += 1;
return n;
};
}
const counter = makeCounter();
console.log(counter()); // 1
console.log(counter()); // 2
- 클로저는 강력하지만, 불필요하게 큰 객체를 잡고 있으면 메모리 누수처럼 보일 수 있으니 주의가 필요합니다.
- 루프에서 콜백을 만들 때는
var대신let을 쓰면 의도치 않은 동작을 줄일 수 있습니다.
setTimeout / setInterval: ‘시간’은 정확하지 않을 수 있습니다
타이머는 “정확히 그 시간에 실행”이 아니라, 그 시간 이후에 실행될 수 있도록 큐에 올리는 것에 가깝습니다. 그래서 이벤트 루프와 함께 이해하면 훨씬 자연스럽습니다.
const id = setInterval(() => {
console.log('tick');
}, 1000);
setTimeout(() => clearInterval(id), 5000);
실무 팁
- 타이머 정리는 항상
clearTimeout/clearInterval까지 함께 챙겨두시면 안전합니다. - Promise의 then/catch는 Microtask로 처리되는 경우가 많아서, 일반 타이머(Task)보다 먼저 실행될 수 있습니다.
참고 링크
'Tech Note > 웹-JavaScript' 카테고리의 다른 글
| [심화] 06. Promise·async/await·Generator (0) | 2026.01.04 |
|---|---|
| [심화] 05. this·프로토타입·클래스 (0) | 2026.01.04 |
| [심화] 03. 배열 메서드·구조 분해 할당 (0) | 2026.01.04 |
| [심화] 02. Symbol·Number·String (0) | 2026.01.04 |
| [심화] 01. 호이스팅·TDZ·생성자 함수 (0) | 2026.01.04 |