hmk run dev

자바스크립트 실행 컨텍스트(Excution Context) 본문

javascript

자바스크립트 실행 컨텍스트(Excution Context)

hmk run dev 2022. 3. 20. 12:54

실행 컨텍스트는 한마디로

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

- 코드 실행 시 식별자를 더욱 효율적으로 결정하기위한 수단!

 

자바스크립트 코드가 실행되면 싱글 스레드인 자바스크립트 엔진은 가장 먼저 콜 스택에 전역 실행 콘텍스트를 담습니다!

여기서 실행 콘텍스트는 Record와 Outer를 담고 있습니다.

 

그리고 임의의 함수 A가 실행될 경우 함수 A의 실행 콘텍스트가 콜 스택에 담겨서 맨 위에 쌓입니다.

콜 스택에선 가장 최근에 추가된 콘텍스트가 활성화됩니다.

 

그리고 함수 A에서 함수 B가 실행될 경우 콜 스택에 함수 B가 쌓이며 B의 실행환경이 활성화됩니다.

그리고 LIFO 방식으로 B의 함수가 실행되고 사라지고 그다음은 A 그다음은 전역 상태가 실행되며 사라집니다.

 

싱글 스레드인 자바스크립트의 콜 스택에 함수가 쌓이고 LIFO으로 사라지는 것에 대해서 간단하게 세부적으로 알아보겠습니다!

 

 


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

 

자바스크립트는 변수 선언부 위에서 변수를 출력해도 에러가 발생하지 않고 undefined를 출력함

이렇게 선언 라인 전에도 에러가 나지 않고 변수를 참조할 수 있는 현상을

선언문이 마치 최상단으로 끌어올려진 듯 해 호이 스팅이라고 합니다.

 

선언문을 물리적으로 최상단으로 끌어올린 게 아니라

자바스크립트 엔진이 먼저 전체 코드를 스캔하면서 변수와 같은 정보를 실행 콘텍스트에 미리 기록을 해놓기 때문입니다.

console.log(name); // undefined - var를 사용했기 때문에 기본적으로 undefined가 할당됨

-> es6에서 추가된 const, let 사용 시 변수를 선언 시 Reference 에러 발생! 
-> 선언라인 이전에 변수참조 불가능

var name = "hmk"; // 선언은 위에서 하고 hmk를 할당한다.

console.log(name); // 'hmk'

이때 이러한 정보들을 저장해놓는 곳이 레코드입니다.

 

환경 레코드 (environment Record)

- 식별자와 식별자에 바인딩된 값을 기록해 두는 객체

 

호이 스팅은 두 가지로 나눌 수 있습니다.

 

변수 호이 스팅(Variable Hoisting)

위에서 말했다시피 자바스크립트는

 

1. 전역 실행 콘텍스트를 생성해 콜 스택에 넣습니다.

2. 전체 코드를 스캔 후 선언할 게 있는지 찾아보고 있다면 먼저 선언해둡니다.

3. 선언하는 과정에서 생성해둔 실행 콘텍스트 안에 있는 환경 레코드에 새로운 식별자 name을 기록합니다.

 

그리고 var로 선언했기 때문에 undefined로 값을 초기화해줍니다.

 

이러한 단계를 생성 단계(Creation phase)라고 합니다.

- 선언문만 실행해서 environment Record에 기록

 

 

그리고 이어서 선언문 외에 나머지 코드를 순차적으로 실행하는 것을

실행단계(Excution phase)라고 합니다.

- 필요한 경우 생성 단계에서 기록해둔 정보를 참고하거나 업데이트하게 됨

 

 

함수 호이 스팅(Function Hosisting)

 

함수 표현식

study(); // var 선언해 undefined로 초기화 되지만 변수와 달리 함수는 호출될 수 없어서 type error 발생
// let, const로 선언 시 레코드 값을 초기화 해두지 않아 Reference error 발생

var study = () => {
	// to do 
}

위처럼 함수를 변수에 담아 표현하는 방식을 함수 표현식이라고 합니다.

변수 호이 스팅과 동작 방식이 같음

 

 

함수 선언문

study();

function study() { 
	// to do
}

함수 선언과 동시에 완성된 함수 객체를 레코드에 저장 { study : f {} }

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

선언 전에도 함수를 사용할 수 있게 되어 사용을 지양하고자 하는 의견도 있습니다.

 


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

외부 환경 참조 (outer environment Reference)

바깥의 Lexical environment를 가리킴

> Lexical environment는 쉽게 말해 Record와 outer를 합친 환경이라고 말할 수 있습니다.

 

let lamp = false;

console.log(lamp);

function goTo2F () {
	let lamp = true;
    
    console.log(lamp);
    goTo3F();
}

goTo2F();

function goTo3F () {
	
    let pet = 'puppy';
    
    console.log(pet); // puppy
    console.log(corona); // ?
}

위의 코드와 그림을 보고 스코프 체이닝을 이해해보자

 

1. 전역 실행 콘텍스트가 콜 스택에 쌓임

- 전역으로 선언한 lamp와 함수 선언문으로 선언한 go To2F가 통째로 레코드에 기록

 

2. goTo2F가 실행되며 새로운 실행환경이 생성, 쌓임

- 이때 lamp의 값을 새로운 실행환경의 값인 true로 참조 (식별자 결정)

 

식별자 결정

콜 스택 안에 동일한 식별자가 여럿일 때 js엔진이 어떻게 outer를 활용해 의사결정을 하는지 알아봅시다!

 

위 그림처럼 전역, 실행되는 함수 환경들은 outer를 이용해 현재 스코프에서 참조할 수 있는 변수 값이 없다면

이전 Lexical 환경에서 참조할 값을 탐색하고 전역 환경까지 탐색합니다.

 

변수 섀도잉

위 코드 goTo2F 실행환경에선 lamp의 값은 true로 상위 스코프의 false값을 출력하지 않는다.

이 처럼 동일한 식별자로 인해 상위 스코프의 식별자 값이 가려지는 현상을 뜻함

 

스코프체인

식별자를 결정할 때 활용하는 스코프들의 연결리스트 (위의 그림에서 사다리!)

 

 

 

 

 

 

 

'javascript' 카테고리의 다른 글

이터레이터 & 제너레이터  (0) 2022.04.18
웹 어셈블리(WebAssembly)를 쓰는 이유  (0) 2022.03.28
스코프 & 클로저 & this 개념말고 실전 (feat. vue)  (0) 2022.01.12
javascript loop  (0) 2021.12.22
마우스 오버이벤트  (0) 2021.11.14
Comments