실행 컨텍스트란?
실행할 코드에 필요한 환경 정보를 모아놓은 객체
- 전역공간, 함수, 블록에 의한 활성화 방법이 있다
- 함수가 실행될 때 생성되어 스택에 쌓이고, 가장 위의 있는 컨텍스트와 관련있는 코드를 실행한다
*전역 실행 컨텍스트는 별도의 전역 객체 활용(브라우저 - window, node.js - global)
1. 실행 컨텍스트 구성 순서
함수 실행문 → 실행 컨텍스트 활성화(객체 생성) → 호이스팅(내부환경 정보 구성) → 외부환경 정보 구성 → this바인딩
2. 함수 실행 과정
- js파일이 열리는 순간 전역 컨텍스트가 활성화된다.
- 코드 실행 중 내부 함수 실행문을 만나면 진행을 멈추고 내부 함수의 코드를 실행시킨다.
- 내부 함수 실행이 끝나면 멈추어진 시점으로 돌아가 다시 진행한다.
3. 실행 컨텍스트 구조
VariableEnvironment
- 현재 컨텍스트 내의 식별자들에 대한 정보 + 외부 환경 정보
- 선언 시점의 스냅샷으로 변경사항은 반영되지 않음
LexicalEnvironment
- 처음에는 VariableEnvironment과 같지만 변경사항이 실시간으로 반영됨
ThisBinding
VariableEnvironment
ㄴ environmentRecode(스냅샷)
ㄴ outerEnvironmentReference(스냅샷)
LexicalEnvironment
ㄴ environmentRecode
ㄴ outerEnvironmentReference
ThisBinding
LexicalEnvironment와 호이스팅
1. 호이스팅이란
실행 전 코드를 한번 쭉 훑으면서 식별자를 LexicalEnvironment에 순서대로 수집하는 것
- LexicalEnvironment에는 현재 컨텍스트 내의 식별자들에 대한 정보들이 저장됨
- 매개 변수 식별자, 함수 선언, 변수 식별자를 수집 (선언만)
- 코드가 실행되기 전에도 js엔진이 해당 환경의 식별자를 알고있다
2. 특징
- 매개변수도 내부 변수와 호이스팅 과정이 같다
- 같은 식별자의 선언이 중복되면 무시된다
- 선언부분만 수집되고 할당엔 관심이 없다
3. 주의할 점
- var키워드의 변수는 선언과 동시에 undefind가 할당된다
- 변수 선언문 전에 사용해도 동작한다(undefind가 나올 뿐)
- 함수 선언식은 선언과 동시에 할당된다
- 함수 선언 전에 실행시켜도 문제없이 동작한다
- 그러나 읽을 때 자연스럽지 않다
- 중복 선언 시 오버라이딩되어 의도치 않은 문제가 생길 수 있다
⇒ let과 const는 실행 시에만 값이 할당되기 때문에 변수 선언+함수 할당 전 사용을 방지할 수 있다(에러뜸)
⇒ 함수는 표현식으로 작성해야 변수 선언+함수 할당 전 실행을 방지할 수 있다 (익명함수나 화살표 함수를 변수에 할당해서 사용)
스코프와 스코프 체인
1. 스코프란?
- 식별자에 대한 유효범위
- 함수 실행 시 그 함수의 컨텍스트에 담긴 정보만 사용할 수 있는 것
(environmentRecode, outerEnvironmentReference)
2. 스코프 체인이란?
- 식별자의 유효범위를 안에서부터 바깥으로 차례로 검색해나가는 것
3. 체인 연결 과정
- 전역 컨텍스트가 생성되어 변수, 함수 선언을 수집 후 코드 실행
- 실행 중에 이미 수집된 함수 또는, 함수가 할당된 변수가 실행되는 코드를 만나면 해당 내부함수의 컨텍스트 활성화
- 내부 함수 자신의 스코프 내부의 식별자들을 환경 레코드에 수집
- 외부환경참조속성에 외부 함수의 환경레코드 주소를 연결
- 이후 내부 함수에서 함수가 실행문을 만날 경우 1~4번 반복
4. 스코프 체인에 의한 변수 탐색 과정
- 자신의 환경 레코드에서 사용하려는 변수 탐색
- 없을 경우 외부 환경 참조 속성을 통해 부모 스코프의 환경 레코드를 탐색하고,
- 그곳에도 없을 경우 부모 스코프의 외부환경참조속성을 통해 조상 스코프의 환경 레코드를 탐색하는 과정을 반복한다
주의 할 점
외부 함수와 내부함수에 같은 이름의 변수가 있는 경우, 외부 함수의 변수는 참조하지 못한다 .
= 변수 은닉화
전역변수와 지역변수
전역변수 - 전역스코프에 속해있는 변수들
지역변수 - 전역스코프 제외한 함수 내부에 속해있는 변수들
*전역변수는 모든 스코프에서 접근, 변형할 수 있기 때문에
오버라이딩되어 의도치않은 문제가 될 수 있어 되도록 사용을 최소화하는 것이 좋다