Javascript는 컴파일 단계가 있는 정적언어가 아니라 동적으로 실행을 통해 상태가 결정되는 동적 언어다. 이 같은 특성을 가진 언어들은 동적으로 변수나 상태를 해석해야 하기 때문에 코드가 실행될 때 환경을 저장하는 특징이 있다. 이를 실행 컨텍스트(Excution Context)라고 한다.
Javascript의 실행 컨텍스트는 3가지 경우가 있다. 전역 컨텍스트, eval 함수, 함수 실행이다. 이 중에 주로 사용하는 함수 실행 기준으로 확인해보겠다.
실행 컨텍스트의 구성은 다음과 같다.
Variable Environment를 구성하고 Lexical Environment에 복사하여 저장한다. 그리고 이후 Lexcal Environment는 변경사항들을 실시간으로 저장하게 된다. 즉, Variable Environment는 생성 당시의 스냅샷(원본), Lexical Environment는 실시간 추적 객체이다. Variable Environment와 Lexical Environment의 형태는 같기 때문에 Lexical Envrionment에 대해 정리하겠다.
Lexical Envrionment는 Environment Record와 Outer Environment Reference를 가지고 있는데 전자는 현재 컨텍스트의 실행 정보이고 후자는 외부 스코프의 Lexical Envrionemnt를 참조하는 객체이다.
Javascript가 실행되면 우선 전역 컨텍스트를 실행한다. 실행하는 과정 중에 함수를 만나면 새로운 함수 컨텍스트를 생성한다. 생성 당시의 변수, 함수 선언문과 같은 식별자를 수집하게 된다. 컨텍스트는 스택(Stack)로 쌓이게 된다.
Stack FILO(First In Last Out)형태를 띈 자료구조로, 먼저 들어온 것이 나중에 나가는 방식이다.
스택 가장 상단에 있는 컨텍스트부터 실행하여 차례로 실행하게 된다.
사용하는 변수가 상단으로 끌어올려지는 것처럼 작동하는 방식을 말한다.(실제로는 끌어올리지 않음) 호이스팅은 변수 혹은 함수 선언과 같은 정보에서 발생한다.
var a = 1;
function outer() {
function inner() {
console.log(a);
var a = 3;
}
inner();
console.log(a);
}
outer();
console.log(a);