자바스크립트를 사용하면서 왜 이런 결과가 나오는지 명확히 설명하지 못하는 순간들이 반복됐다.
단순히 비동기, 호이스팅 같은 키워드를 아는 것과 실제 실행 흐름을 이해하는 것은 다르다고 느껴졌다.
그래서 자바스크립트 실행 모델 자체를 깊게 파고드는 것을 목표로 학습해봤다.
이벤트 루프, 콜스택, 실행 컨텍스트, 스코프를 각각 따로 외우는 것이 아니라
하나의 실행 흐름으로 연결해서 이해하는 데 집중했다.
이번 학습에서 가장 크게 느낀 점은
자바스크립트의 많은 동작은 값이나 코드 위치가 아니라 실행 시점에 의해 결정된다는 사실이었다.
같은 코드라도
이 관점을 잡은 이후, 헷갈리던 비동기 동작들이 하나의 흐름으로 정리되기 시작했다.
콜스택은 단순히 함수 호출 순서를 저장하는 구조가 아니다.
자바스크립트에서 실행 여부를 결정하는 절대적인 기준이다.
즉, 비동기는 '동시 실행'이 아니라 '실행 권한을 나중에 요청하는 구조'라는 점을 이해했다.
이벤트 루프는 코드를 실행하는 주체가 아니다.
대신 다음 실행 대상을 선택하는 관리자 역할을 한다.
동작 순서를 명확히 정리해봤다.
중요한 점은
큐에 있다는 사실 자체는 실행을 보장하지 않는다는 점이었다.
실행은 오직 콜스택에 올라갔을 때만 이루어진다.
setTimeout(fn, 0)이 즉시 실행되지 않는 이유를 단순히 '비동기니까'가 아니라 보다 구조적으로 이해하게 됐다.
즉, setTimeout의 실행 시점은 시간이 아니라 콜스택 상태에 의해 결정된다.
자바스크립트 코드는 실행되기 전에 Global Execution Context가 먼저 생성된다.
이 컨텍스트에서는 다음이 수행된다.
중요한 점은
호이스팅은 코드 이동이 아니라 실행 컨텍스트 생성 단계의 작업이라는 사실이다.
console.log(a)
var a = 1
이 코드에서 undefined가 출력되는 이유를 실행 단계 관점에서 이해했다.
var a는 선언되고 undefined로 초기화된다.a = 1이 할당된다.이로 인해 var는
이 차이는 단순 문법 차이가 아니라 변수 생명주기와 참조 방식의 차이였다.
for (var i = 0; i < 3; i++) {
setTimeout(() => console.log(i), 0)
}
이 코드가 3 3 3을 출력하는 이유를 이벤트 루프 + 스코프 + 실행 시점 관점에서 분석해봤다.
핵심은 다음과 같았다.
1. var는 함수 스코프라 i가 하나만 존재한다.
2. for문은 동기 코드라 콜스택을 계속 점유한다.
3. 콜백은 실행되지 않고 큐에서 대기한다.
4. for문 종료 후 i는 3이 된다.
5. 콜백은 실행 시점의 i를 참조한다.
특히 for문의 증감식이 마지막 조건 비교 전에 한 번 더 실행된다는 점을 놓치고 있었다는 사실을 인지하면서,
왜 2 2 2가 아닌 3 3 3인지 완전히 납득할 수 있었다.
마무리
이번 학습을 통해
자바스크립트를 되는 대로 사용하는 단계에서 왜 그렇게 동작하는지 설명할 수 있는 단계로 한 단계 올라갔다고 느꼈다.
🧐 코드가 아닌 실행 모델 관점에서 먼저 사고하기