자바스크립트를 접했을 때, 흥미로운 개념들이 많아 특히 실행 컨텍스트에 대해 재미있게 배웠던 기억이 있다. 하지만 코딩을 하면서 실행 컨텍스트가 기초가 되는 개념임을 다시금 실감하게 되었고, 이에 한 번 더 자세히 기록해보려 한다.
console.log(a); // undefined
var a = 10;
실행 컨텍스트 생성 단계에서 a
가 먼저 메모리에 등록되므로 에러가 발생하지 않고 undefined
가 출력 된다.
this
값을 결정한다. this
값은 어떤 방식으로 함수가 호출되었는지에 따라 달라진다.(예: 전역, 객체 메서드, 생성자 함수 등)위 3가지 특징에 대해서는 중요한 개념이기에 따로 집중적으로 다뤄야겠다-!!
또한, 스택과 큐의 동작 원리를 알아야 자바스크립트의 실행 컨텍스트 생성, 제거 과정뿐 아니라 비동기 코드의 실행 순서까지 명확히 이해할 수 있다.
자바스크립트는 싱글 스레드 언어로, 코드 실행 순서를 관리하기 위해 스택
이라는 구조를 사용한다. 실행 컨텍스트가 생성되고 종료되는 과정에서 호출 스택에 쌓이고 제거되는데, 이를 이해하지 못하면 함수 호출이 중첩되었을 때 코드가 실행되는 순서를 예측하기 어렵다.
a, b, c, d
를 저장했다면 꺼낼 때는 반대로 d, c, b, a
의 순서대로 꺼내는 후입선출 구조(LIFO)를 가진다.자바스크립트는 비동기 작업을 처리하기 위해 이벤트 루프
와 태스크 큐
를 활용한다. 비동기 작업의 실행 순서를 이해하려면 큐에 작업이 쌓이는 원리와, 이 큐가 스택과 상호 작용하는 방식을 알아야 한다.
a, b, c, d
를 저장했다면 꺼낼 때도 역시 a, b, c, d
의 순서로 꺼낼 수 밖에 없는 선입선출 구조(FIFO)를 가진다.동일한 환경에서 실행되는 코드들은 실행에 필요한 환경 정보들로 실행 컨텍스트를 구성한다. 이 실행 컨텍스트는 콜 스택에 쌓이고, 가장 위에 쌓인 컨텍스트가 활성화되어 실행된다. 실행 컨텍스트는 전역 코드, 함수 호출, eval()
실행 시 각각 생성된다.
참고로 eval() 함수는 보안상 취약점이 많이 악마로 비유되며, 사용을 최대한 지양해야 한다.
실행 컨텍스트와 콜 스택의 동작을 확인하기 위해 예시 코드를 가져왔다.
// ----------------------- (1)
var a = 1;
function outer() {
function inner() {
console.log(a); // undefined
var a = 3;
}
inner(); // ---------- (2)
console.log(a); // 1
}
outer(); // -------------- (3)
console.log(a); // 1
전역 컨텍스트
코드 실행이 시작되면 전역 실행 컨텍스트가 콜 스택에 쌓인다. 이는 코드 전체를 감싸는 최상위 컨텍스트다.
outer
함수 호출
outer()
가 호출되면, 새로운 실행 컨텍스트가 생성되어 콜 스택에 쌓인다. 이 컨텍스트는 outer
함수의 스코프와 변수 정보를 포함한다.
inner
함수 호출
inner()
가 호출되면, 또 다른 실행 컨텍스트가 생성되어 콜 스택의 최상단에 추가된다. 이 시점에서 변수 a
는 inner
함수 내부에서 다시 선언되었으므로, 출력 결과는 undefined
가 된다(변수 호이스팅).
inner
함수 종료
inner()
실행이 완료되면 해당 실행 컨텍스트도 콜 스택에서 제거된다.
outer
함수 종료
outer()
의 실행이 완료되면 해당 실행 컨텍스트도 콜 스택에서 제거된다.
전역 컨텍스트 실행 종료
모든 함수 호출이 끝나면 전역 컨텍스트의 나머지 코드가 실행되며, 마지막으로 전역 컨텍스트가 스택에서 제거된다.
전역 컨텍스트는 자바스크립트 파일이 로드되거나 스크립트가 실행되는 순간 자동으로 활성화된다. 이는 별도의 명령 없이도 실행되는 최상위 환경이다.