JavaScript 데이터 - 코드 실행 2단계와 변수/함수 생성과정, 호이스팅 원리

2022. 2. 21. 11:52공부/Javascript

[자바스크립트] 코드 실행 2단계와 변수/함수 생성 과정 (tistory.com)

 

[자바스크립트] 코드 실행 2단계와 변수/함수 생성 과정

자바스크립트는 소스 코드를 2단계로 실행합니다. 1 단계: 실행 컨텍스트 생성하고, 변수 등을 등록하는 단계 2 단계: 소스 코드를 한 줄씩 실행하는 단계 이 글은 각각의 과정을 최대한 단순화하

curryyou.tistory.com

위 블로그 글 백업용.

// 변수 선언문
var a = 10; 
let b = 20; 
const c = 30; 

// 함수 선언문 
function func_1(arg){ return arg; } 

// 함수 표현식(var) 
var func_2 = function(arg){ return arg; } 

// 함수 표현식(const/let) 
const func_3= function(arg){ return arg; }

위 코드를 실행한다고 가정한다.

 

1 Step: 생성 단계(Creation Phase)

자바스크립트는 소스코드 실행 전 소스코드 전체를 훑으며 문제를 체크한다.

이 과정에서 실행컨텍스트를 생성, 변수 및 함수를 등록한다.

이 과정을 소스코드 평가 과정, 소스코드 스캔 과정이라고도 한다.

 

실행 컨텍스트(Execution Context)

- 자바스크립트가 코드를 실행하기 위해 관리하는 Stack 구조의 실행 환경

- 이 구조를 통해 실행 시점의 변수, 함수, this, 스코프 등을 관리하며 명령어로 실행해 나감.

 

렉시컬 환경(Lexical Environment)

- ECMAScript 명세서에서 '자바스크립트 엔진이 변수를 어떻게 관리해야 하는지'를 기술하기 위해 사용된 명칭

- 실행컨텍스트의 컴포넌트로 변수 및 스코프, this 등을 관리하기 위한 추상적인 이론상의 개념. 구체적인 객체는 아님.

- 자바스크립트 엔진들은 각기 다른 방식으로 ECMAScript의 렉시컬환경의 사항을 준수하며 변수 환경을 관리한다.

 

1 Step에서 일어나는 일을 단순하게 도식화하면 다음과 같다.

소스코드에서 변수/함수 선언된 곳을 찾아 실행컨텍스트의 렉시컬 환경이라는 곳에 식별자(a, b, c, func_1, func_2, func_3)을 등록한다.

 

변수

1. var

a) var a를 발견하면 실행컨텍스트의 렉시컬환경에 변수를 등록

- 렉시컬 환경 내부의 객체 환경 레코드(Object Environment Record)에 등록됨

- 따라서 전역객체인 window.a 등으로 참조가 가능하다.

b) 콜스택에 데이터 저장을 위한 메모리를 할당

c) 해당 콜스택 메모리의 주소값을 변수에 저장

d) 확보된 콜스택 메모리에는 'undefined'를 할당(초기화)

- var로 선언된 변수는 선언문 앞에서도 참조할 수 있다. => HOISTING

 

2. const / let

a) let b, const c 코드를 발견하면 실행컨텍스트의 렉시컬 환경에 변수를 등록하고 끝난다.

- 렉시컬 환경 내부의 선언적 환경 레코드(Declarative Environment Record)에 등록됨.

- 전역객체인 window.b 등으로 참조할 수 없다.

b) 이 상태에서 변수를 참조하면 ReferenceError가 발생한다. (Temporary Dead Zone)

 

함수

1. 함수 선언문 (function으로 생성)

a) function func_1 을 발견하면 실행컨텍스트의 렉시컬환경에 함수 식별자(func_1)를 등록

b) 메모리 힙에 공간 확보 후 콜스택에 메모리 힙의 주소 저장

c) 함수 변수(func_1)에 콜스택의 주소를 저장

d) 메모리힙에 함수 내용을 저장함.

- 완전 호이스팅되어 함수 선언문 앞에서도 함수를 호출할 수 있다.

 

2. 함수 표현식(var, let/const로 생성)

a) 변수와 동일하게 작동한다.(var, let/const에 따라 다름)

- var로 선언된 함수에는 undefined가 할당

- const/let으로 선언된 함수는 참조 불가능

 

2 Step: 실행 단계(Execution Phase)

실제 코드를 한 줄 씩 해석하며 실행해나가는 단계. '런타임(Runtime)'이라고 불림.

변수

1. var

a) a = 10; 코드를 만나면

b) 콜스택에 확보되어 있던 메모리(undefined) 말고 새로운 메모리를 다시 확보해 실제 값(10)을 저장.

c) 변수 a에도 새로운 콜스택 주소값을 저장함

 

2. let / const

a) let b = 20; const c = 30; 코드를 만나면

b) let b, const c 부분에서 메모리를 확보하여 undefined를 할당하고

c) undefined가 저장된 콜스택 메모리 주소값을 변수에 저장하고

d) b = 20; c = 30; 부분에서 다시 새로운 메모리를 확보해 실제값을 저장.

e) 새로운 콜스택 메모리의 주소값을 변수 b, c에 다시 저장(교체)

 

함수

1. 함수 선언문

- 1단계(생성단계)에서 이미 함수 식별자 및 구현부까지 메모리에 할당이 완료된 상태다.

2. 함수 표현식

- 변수와 동일하게 작동한다.

 

세부 과정은 엔진마다 다르고 훨씬 더 복잡함.