프론트엔드 개발

[우아한 Tech] - 실행컨텍스트 본문

후기/Teck Talk

[우아한 Tech] - 실행컨텍스트

태나미 2021. 11. 30. 22:12
유튜브 채널 우아한 Tech에서 본 영상을 다시 글로 보기 위해 만들었습니다.
이미지와 내용 출처는 하단에 있습니다. 

이번 내용은 실행컨텍스트 구성 중 Record와 Outer에 집중하여 보겠습니다.

목차

1. Record(EnvironmentRecord)로 JS 호이스팅 이해하기

2. Outer(Outer Environment Reference)로 JS 스코프체이닝 이해하기

3. Execution Context 정리

1. Record로 JS 호이스팅 이해하기

console.log(laptop); // undefined

var laptop = "macbook";

console.log(laptop); // macbook

위 예제 첫번째 줄에서 호이스팅이 발생하여 undefined를 출력되는 것을 볼 수 있습니다.

*호이스팅이 발생하는 이유는 자바스크립트 엔진이 변수 같은 정보를 실행컨텍스트의 Record에 미리 기록해 놓기 때문입니다.

이 Record의 정식 명칭은 Environment Record로, 식별자와 식별자에 바인딩된 값을 기록해두는 객체입니다.

Variable Hoisting

1) var

console.log(laptop); // undefined

var laptop = "macbook";

console.log(laptop); // macbook

자바스크립트 엔진은 환경 레코드에 새로운 식별자를 laptop을 기록합니다.

var 키워드로 선언했기 때문에, undefined로 값을 초기화해둡니다.

선언 이후 값을 할당한 뒤, 바인딩된 값을 'macbook'으로 업데이트합니다.

마지막 라인은, 자바스크립트 엔진은 환경 레코드를 참조해서  laptop의 값을 'macbook'으로 결정합니다.

 

2) const

console.log(laptop); // Reference Error

const laptop = "macbook";

console.log(laptop); // macbook

자바스크립트 엔진이 laptop식별자를 기록해두긴 하지만, 값을 초기화하지 않습니다. 따라서 선언문 이전에 laptop을 참조하고자 하면 Reference Error가 발생합니다. let이나 const로 선언한 변수는 선언 라인 이전에 변수에 참조할 수 없는데, 이 구역을 일시적 사각지대라고 부릅니다.

일시적 사각지대 (Temporal Dead Zone)
선언 이전에 식별자를 참조할 수 없는 구역

어떤 키워드를 쓰느냐에 따라 차이가 발생하는 이유

var 키워드로 변수를 선언한 경우, 선언과 초기화가 동시에 진행됩니다.

선언 단계: 메모리 공간 확보 후, 메모리 주소에 식별자를 연결

초기화 단계: 식별자를 undefined값으로 초기화

 

let, const 키워드로 변수를 선언한 경우, 값을 undefined로 선언하지 않기 때문에 할당 문 직전까지 변수에 아무런 값이 담겨 있지 않아, 접근하고자 하면 error가 발생합니다. 선언 라인 이전에 변수를 참조할 수 없다는 것을 의미합니다.

Function Hoisting 

1) Function Expression

(1) var 키워드로 선언한 경우

study(); // Type Error
 
var study = () => {
    // do something
}

자바스크립트에서는 함수를 변수에다가 담을 수 있는데, var 키워드로 선언한 것을 선언문 이전에 실행하려고 하면, 환경 레코드에 기록되어 있는 study의 값은 undefined이고, 이 데이터 타입은 호출될 수 없기 때문에 Type Error가 발생합니다.

 

(2) const 키워드로 선언한 경우

study(); // Reference Error
 
const study = () => {
    // do something
}

const 키워드로 선언하면, 아직 환경 레코드에 기록된 값이 없어 Reference Error가 발생합니다.

함수 표현식
- 변수 호이스팅과 동일하게 동작
- 변수에 함수를 담아서 함수를 선언하는 방식

2) Function Declation

study();

function study(){
    // do study
}

위와 같이 함수를 선언하는 경우에는 자바스크립트 엔진이 함수의 선언과 동시에 완성된 함수 객체를 생성해 환경 레코드에 기록합니다. 위 study 함수는 에러 없이 실행되는데, 선언문의 특징은 선언과 동시에 함수가 생성됩니다.

함수 선언문
- 선언과 동시에 함수가 생성되어 선언 전에도 함수를 사용할 수 있음

함수 선언문과 함수 표현식의 차이점 - Environment Record에 어떻게 저장되는지 아래 그림을 보면서 확인할 수 있습니다.

2. Outer로 JS 스코프체이닝 이해하기

Question

- 위 그림에서 lamp를 출력하려고 환경 레코드를 보니, lamp가 두 개가 있는데 어느 것을 출력할지?

- 콜 스택 안에 동일한 식별자가 여럿일 때, 자바스크립트 엔진이 어떻게 outer를 활용해서 의사결정을 할까?(*식별자 결정은 어떻게 할까?)

 

Answer

=> goTo2F를 실행하는 시점을 보면, 새로 생성된 실행컨텍스트에 바깥 렉시컬 환경으로 돌아갈 수 있는 outer를 가지게 되면서, 필요한 경우에 이전 실행컨텍스트의 환경 레코드에 저장된 식별자도 참조할 수 있게 됩니다.

자바스크립트 엔진은 *식별자(lamp)의 값을 결정하기 위해, 현재 활성화된 실행컨텍스트의 환경 레코드를 먼저 봅니다. 활성화된 실행 컨텍스트에서 lamp는 켜져 있기 때문에, true가 출력됨을 알 수 있습니다. goTo2F 실행컨텍스트의 환경 레코드에서 lamp를 찾았기 때문에, 더 이상 스코프체이닝을 하지 않아 전역 컨텍스트의 lamp 값이 어떤 값인지 모르게 됩니다. 이때, *변수 섀도잉 현상이 나타납니다.

 

if, 아래 예시에서, name의 결과 값은?

function goTo2f() {
    let lamp = true;
    
    console.log(name);
}

goTo2f();

=> 현재 활성화된 실행 컨텍스트의 환경 레코드에는 name이 없습니다. 

자바스크립트 엔진은 outer가 가리키는 바깥 렉시컬 환경으로 가서 name을 찾기 시작합니다.

실행 컨텍스트의 outer로 계속 찾다가, 최상위 컨텍스트인 전역 실행 컨텍스트의 환경 레코드까지 찾게 되는데, 이때도 name은 없는 걸 알게 됩니다. 없는 식별자를 참조하려고 했기 때문에 Reference Error가 출력됩니다.

3장 Execution Context

Execution Context

- 코드를 실행하는데 필요한 *환경을 제공하는 객체

- 식별자 결정을 더욱 효율적으로 하기 위한 수단

 

 

참고

* 호이스팅(Hoisting): 선언문이 마치 최상단에 끌어올려진 듯한 현상

* 식별자 결정(Identifier Resolution): 코드에서 변수나 함수의 값을 결정하는 것

* 변수 섀도잉(Variable Shadowing): 상위 스코프에서 선언된 식별자의 값이 가려지게 되는 현상

* 스코프 체인(Scope Chain): 식별자를 결정할 때 활용하는 스코프들의 연결리스트

* 스코프 체이닝(Scope Chaining): 식별자를 결정하기 위해 찾는 과정

* 환경: 코드 실행에 영향을 주는 조건이나 상태

 

 

출처: https://youtu.be/EWfujNzSUmw

 

'후기 > Teck Talk' 카테고리의 다른 글

[우아한 Tech] - 상태관리와 반응형 프로그래밍  (0) 2022.01.05
Comments