자바스크립트는 동적 언어로서 다른 언어와 달리 독특하게 동작하는 경우가 종종 있습니다. 실행 컨텍스트는 자바스크립트가 이런저런 특이하게 동작하는 개념인 "실행 컨텍스트" 에 대해 깁게 학습한 내용에 대해 공유하고자 합니다.
Execution Context ( 실행 컨텍스트 )
실행 컨텍스트는, 코드를 실행하는데 제공할 환경 정보들을 모아놓은 객체입니다. 이 객체에는 식별자들에 대한 정보, 외부 환경 정보, this와 같은 정보들이 저장됩니다.
- VariableEnvironment : 해당 컨텍스트가 최초 실행 될 때의 식별자들의 정보(environmentRecord), 외부 환경 정보 (outerEnvironmentReference)
- LexicalEnvironment : 최초에 VariableEnvrionment를 복사하여 그 값을 가지고, 이후 변경사항이 실시간으로 반영
- ThisBinding : this 식별자가 바라봐야 할 대상 객체
이 실행컨텍스트 객체는 자바스크립트가 동작하는 시점부터 "전역 컨텍스트"가 콜스택에 쌓이게 됩니다. 함수나 모듈을 통해 스코프가 생성되기 전 동작하는 코드들의 환경 정보는 모두 전역 컨텍스트에 쌓이게 되죠. 이후 함수나 모듈을 통해 새로운 컨텍스트가 생성되어 완료될 때까지 콜스택에 쌓여 환경 정보를 관리하게 됩니다.
호이스팅
environmentRecord에 저장할 코드의 식별자 정보를 가져오기 위해, 호이스팅이라는 개념이 적용됩니다. 자바스크립트 엔진에서 코드가 실행되기 전, 해당 환경에 속해있는 변수명, 함수 선언, 매개변수 이름에 대한 정보를 가져와 최상단에 올려놓는다는 개념입니다. 대부분의 다른 언어와 다르게 변수 선언 전에 print나 실행을 시킨다고 해도 Error가 아닌 undefined를 출력하는 이유와 마찬가지입니다. 호이스팅을 통해 이미 코드 실행 전 변수를 선언해서 undefined로 초기화시켰기 때문입니다.
변수명과 달리 함수는 함수선언 전체를 호이스팅 합니다. 따라서 함수를 실행해도 정상적인 결과를 얻을 수 있습니다만, 변수의 값으로 함수를 선언하는 함수표현식의 형태는 호이스팅시 변수로 처리하여 변수명만 호이스팅 하고, 함숫값을 할당하는 부분은 해당 위치에 남아있게 됩니다. 따라서, 함수를 실행했을 때 is not a function 에러가 발생하게 됩니다.
outerEnvironmentReference
LexicalEnvironment의 저장되는 다른 값 outerEnvironmentReference입니다. environmentRecord에서는 환경정보에 대해 저장되었다면, outerEnvironmentReference에서는 외부 환경정보에 대해 저장됩니다. 최초에 실행된 전역 컨텍스트를 제외하고 실행되는 함수/모듈은 상황에 따라 외부의 환경정보에 접근하게 되는 경우가 있습니다. 코드 실행 시 스코프 체인상 가까운 순서부터 탐색해 가장 먼저 발견된 식별자를 사용하게 됩니다.
아래는 outerEnvrionmentReference를 포함하여 실행컨텍스트내 객체에서 값을 가져오는 몇 가지 예제입니다
1번 console.log에서 찍히는 a가 실행되는 시점을 살펴보면, 전역 객체에 있는 a를 가져올 것처럼 되어있습니다. 하지만, 호이스팅을 통해 이미 test함수 내에서 선언된 a 변수명을 가져온 상태임으로 실행되면서 undefined를 출력하게 됩니다.
2번 console.log 같은 경우는 함수의 매개변수를 통해 바로 가져오는 경우입니다. 스코프 체인상 가장 가까운 식별자의 값을 가져오기 때문에 30을 출력하게 됩니다.
3번의 경우입니다. 해당 컨텍스트 내 a로 선언된 값이 없으므로 outerEnvironmentReference를 통해 전역 컨텍스트 속 a 값을 가져와 10을 출력하게 됩니다.
마무리
이렇게 실행 컨텍스트에 대해 정리해 봤습니다. 다른 문맥과 개념을 정리하다가 Lexical Environment가 뭔지 몰라서 공부하다 보니 해당 내용을 한번 정리하게 되었고 "코어 자바스크립트"의 내용을 많이 참조하였습니다. 실행 컨텍스트의 thisBinding에 대해서는 따로 아티클로 정리하려고 합니다.
'JavaScript' 카테고리의 다른 글
[Javascript/React] URL Params를 통해 데이터가 원하는데로 전달되지 않을때? ( URL Encoding ) (2) | 2024.10.24 |
---|---|
Variables - var, let, const (1) | 2022.10.11 |
CORS policy와 Import/Export (0) | 2022.10.10 |
Element의 기준으로 다른 요소를 찾기 (0) | 2022.10.08 |
Element의 기준으로 요소 삽입 (0) | 2022.04.16 |