Creation(Pre-parsing) Phase : 코드 실행에 앞서 변수와 함수가 어떻게 정의되어 있는지 분석. 변수 선언과 함수 선인이 등록되지만 초기화는 되지 않음
Execution Phase : 코드가 실제로 실행되면서 변수에 값이 할당되고, 함수가 실행. 이 단계에서 선언된 변수들이 초기화되고, 코드 로직이 순차적으로 실행
이 두 단계는 자바스크립트 엔진이 자바스크립트 코드를 처리하는 기본 방식이며, 함수의 실행과 파일의 실행 모두 동일한 원리로 작동한다.
01. 자바스크립트 엔진 구성 : Stack + Heap
💡 실행 방식
자바스크립트는 싱글 스레드로 실행.
💡 메모리 구조
Stack : 함수의 실행 순서를 관리. 함수 실행 순서대로 적재 및 수행 => 실행 컨텍스트
Heap : 선언 및 할당된 변수 및 함수 저장. => 렉시컬 환경
02. 자바스크립트 엔진 내 함수 동작원리 : Stack(실행 컨텍스트) + Heap(렉시컬 환경)
#1. 스택과 실행 컨텍스트
: 실행 컨텍스트는 함수가 호출될 때마다 생성되는 객체로, 해당 함수의 실행에 필요한 모든 정보를 담고 있다. : 실행 컨텍스트는 함수가 호출될 때마다 스택에 쌓이며, 함수 실행이 끝나면 스택에서 제거.( = 스택은 함수의 실행 순서를 관리하며, 각 함수의 실행 상태를 나타내는 실행 컨텍스트를 적재하고 관리)
#2. 힙과 렉시컬 환경
: 렉시컬 환경은 코드가 작성된 환경을 참조하는 구조.( = 자바스크립트 엔진이 변수와 함수 선언을 관리하고, 스코프 체인을 통해 변수 접근을 처리하는데 사용되는 내부 구조) 이 구조는 변수와 함수 선언을 포함하며, 해당 코드가 실행될 때 변수와 함수가 어디서 어떻게 접근할 수 있는지를 결정. : 함수가 정의될 때의 렉시컬 환경이 힙에 저장되며, 이 환경이 나중에 함수 실행 시 참조. : 렉시컬 환경이 참조하는 데이터가 힙에 저장.
↓
Stack에 저장되는 실행 컨텍스트 : 함수가 실행될 때, 해당 함수의 실행 환경이 Stack에 쌓임. 이 실행 컨텍스트는 함수가 어떻게 실행되어야 하는지를 관리
Heap에 저장되는 렉시컬 환경 : 함수가 정의될 때 생성되는 환경. 함수가 실행될 때 변수와 함수의 스코프를 관리. 렉시컬 환경은 주로 함수, 변수, 상수와 관련된 정보를 담고 있음
< 렉시컬 환경과 변수 환경 > 렉시컬 환경 : 함수나 블록 내부에서 사용되는 let, const 변수, 함수 선언이 관리되는 공간 -> 블록 스코프를 따름 변수 환경 : var 변수들이 이 공간에서 관리 -> 함수 스코프를 따름
03. 실행 컨텍스트
실행 컨텍스트는 자바스크립트 함수가 실행될 때 해당 함수의 실행 환경을 위한 메모리 영역이다.
프로그램이 실행되면, 운영체제는 메모리와 CPU 자원을 할당하여 프로세스를 생성한다. 자바스크립트에서는 함수가 실행될 때마다 해당 함수의 실행을 위한 메모리 영역이 할당되며, 이 메모리 영역을 실행 컨텍스트라 하는 것이다.
자바스크립트에서 함수가 실행되기 위해 필요한 모든 정보는 실행 컨텍스트에 저장된다.
💡 실행 컨텍스트 구성 요소
렉시컬 환경 : let, const 변수와 함수 선언을 관리하는 스코프
변수 환경 : var로 선언된 변수를 관리하는 스코프
💡 글로벌 실행 컨텍스트
자바스크립트에서 모든 코드 실행은 글로벌 실행 컨텍스트로 시작한다.
이는 다른 프로그램에서의 main()함수와 같은 역할을 한다.
글로벌 실행 컨텍스트는 Global Object 전역 객체를 갖는다.
Node.js 환경에서는 global
웹 브라우저에서는 window
#1. Creation(Pre-parsing) Phase
Creation(Pre-parsing) Phase는 자바스크립트 엔진이 코드를 실행하기 전 먼저 변수와 함수의 선언을 분석하고 메모리에 적재하는 단계이다. 이 단계에서 변수와 함수는 선언되지만, 초기화는 실행 단계에서 이루어진다.
◼︎ 변수 선언 & 호이스팅
- var : 변수를 선언과 동시에 초기화. 초기화된 값은 undefined
- let & const : 변수 선언만 호이스팅. 초기화는 실제 코드에 도달했을 때 이루어지므로, 초기화 전에는 ReferenceError 발생
- 함수 선언도 호이스팅되며, 함수 전체가 메모리에 적재. 함수는 선언된 시점에 메모리에 등록되므로 선언 전에 호출 가능
변수를 찾을 때 현재 스코프에서 변수가 없으면, 상위 스코프를 순차적으로 탐색한다. Scope Chain시 어디에도 없으면, Global내 선언 후 할당한다. let은 선언과 동시에 초기화되지 않기 때문에, 선언은 되었지만 초기화되어 있지 않아서 RefereceError가 발생한다.
◼︎ 함수 실행
함수가 실행되면, 함수 선언 시점의 렉시컬 환경을 기반으로 메모리 영역이 확보되며, 확보된 메모리 영역 내에서 함수가 실행된다.
💡 TDZ(Temporal Dead Zone)
TDZ는 let과 const가 호이스팅된 후 초기화되기 전까지의 시간 구간이다.
이 구간에서 해당 변수에 접근하면 ReferenceError가 발생한다.
Creation Phase
해당 단계에서 자바스크립트 엔진은 변수의 선언을 메모리에 등록.
var는 Creation Phase에서 선언 & 초기화를 수행.
let, const의 경우, 초기화는 아직 이루어지지 않는다. 이 단계에서 변수는 존재하지만 초기화되지 않기 때문에 TDZ에 놓이게 됨.
Execution Phase
let은 Execution Phase 에서 초기화 or 할당 을 수행(초기화 전에 변수에 접근하려고 하면 TDZ에 의해 ReferenceError가 발생)
#3. Lexical Scope / Scope Chain / Hoisting
◼︎ Lexical Scope
: 함수가 선언된 위치에 기반. 즉, 함수가 선언될 당시의 스코프가 결정되며, 호출되는 위치와는 무관
◼︎ Scope Chain
: 변수에 접근할 때, 현재 스코프에서 찾을 수 없는 경우 상위 스코프를 차례로 탐색( = Execution Phase 시 변수 선언이 안되어있을때, 호출 순서로 이전 실행 컨텍스트에서 검색)
: Global Execution Context 까지 다 찾아보았음에도 없을 시, 그 자리에 var 선언 및 할당
< Scope Chain 예시 >
🎯 name="nero" 인 경우
var name = 'zero';
function log() {
console.log(name);
}
function wrapper() {
name = 'nero';
log();
}
wrapper();
< 실행 과정 >
var name, function log(), function wrap()가 Global Function 실행 컨텍스트에 선언. 이때 name 변수는 'zero'로 초기화
wrapper()가 호출되면서 새로운 wrapper 실행 컨텍스트가 생성
wrapper 함수 내에서 name에 'nero'를 할당. 이때 name 변수는 var로 선언되지 않았으므로, global Function E.C에 있는 name 변수를 참조하여 값을 변경. -> global Function E.C에 있는 name의 값이 'nero'로 업데이트
wrapper() 함수 내에서 log() 호출
log 실행 컨텍스트가 실행되며, name을 출력하기 위해 global Function E.C에 있는 name을 참조. (3)에서 name의 값은 'nero'로 업데이트 되었으므로, log() 함수는 'nero'를 출력
=> 실행 결과 "nero" 출력
🎯 var name="nero"인 경우
var name = 'zero';
function log() {
console.log(name);
}
function wrapper() {
var name = 'nero';
log();
}
wrapper();
< 실행 과정 >
var name, function log(), function wrap()가 Global Function 실행 컨텍스트에 선언. 이때 name 변수는 'zero'로 초기화
wrapper()가 호출되면서 새로운 wrapper 실행 컨텍스트가 생성
var name="nero"로 선언 및 초기화 진행 -> 이 name 변수는 wrapper() 함수의 로컬 변수로, global Function E.C의 name 변수와는 다른 스코프에 존재
wrapper() 함수 내에서 log() 호출
log 실행 컨텍스트가 실행되며, name이 선언되어 있지 않아 log가 선언되어 있는 global Function E.C에 있는 name 값을 출력
=> 실행 결과 : "zero" 출력
◼︎ Hoisting
: 자바스크립트 엔진이 코드 실행 전에 변수와 함수 선언을 메모리의 상단으로 끌어올리는 현상
[JavaScript] 자바스크립트 내 함수 동작원리 : 실행 컨텍스트(Creation Phase / Execution Phase)
자바스크립트 엔진의 파일 구동 방식은 자바스크립트 함수 구동 방식과 동일하게 처리한다.
변수는 선언과 할당, 함수는 선언과 실행이라는 두 가지 주요 작업을 처리한다.
자바스크립트 엔진의 자바스크립트 함수 구동 방식은 아래 2개의 단계로 나누어 진행된다.
이 두 단계는 자바스크립트 엔진이 자바스크립트 코드를 처리하는 기본 방식이며, 함수의 실행과 파일의 실행 모두 동일한 원리로 작동한다.
01. 자바스크립트 엔진 구성 : Stack + Heap
💡 실행 방식
자바스크립트는 싱글 스레드로 실행.
💡 메모리 구조
02. 자바스크립트 엔진 내 함수 동작원리 : Stack(실행 컨텍스트) + Heap(렉시컬 환경)
#1. 스택과 실행 컨텍스트
: 실행 컨텍스트는 함수가 호출될 때마다 생성되는 객체로, 해당 함수의 실행에 필요한 모든 정보를 담고 있다.
: 실행 컨텍스트는 함수가 호출될 때마다 스택에 쌓이며, 함수 실행이 끝나면 스택에서 제거.( = 스택은 함수의 실행 순서를 관리하며, 각 함수의 실행 상태를 나타내는 실행 컨텍스트를 적재하고 관리)
#2. 힙과 렉시컬 환경
: 렉시컬 환경은 코드가 작성된 환경을 참조하는 구조.( = 자바스크립트 엔진이 변수와 함수 선언을 관리하고, 스코프 체인을 통해 변수 접근을 처리하는데 사용되는 내부 구조) 이 구조는 변수와 함수 선언을 포함하며, 해당 코드가 실행될 때 변수와 함수가 어디서 어떻게 접근할 수 있는지를 결정.
: 함수가 정의될 때의 렉시컬 환경이 힙에 저장되며, 이 환경이 나중에 함수 실행 시 참조.
: 렉시컬 환경이 참조하는 데이터가 힙에 저장.
↓
03. 실행 컨텍스트
실행 컨텍스트는 자바스크립트 함수가 실행될 때 해당 함수의 실행 환경을 위한 메모리 영역이다.
프로그램이 실행되면, 운영체제는 메모리와 CPU 자원을 할당하여 프로세스를 생성한다. 자바스크립트에서는 함수가 실행될 때마다 해당 함수의 실행을 위한 메모리 영역이 할당되며, 이 메모리 영역을 실행 컨텍스트라 하는 것이다.
자바스크립트에서 함수가 실행되기 위해 필요한 모든 정보는 실행 컨텍스트에 저장된다.
💡 실행 컨텍스트 구성 요소
💡 글로벌 실행 컨텍스트
자바스크립트에서 모든 코드 실행은 글로벌 실행 컨텍스트로 시작한다.
이는 다른 프로그램에서의 main()함수와 같은 역할을 한다.
글로벌 실행 컨텍스트는 Global Object 전역 객체를 갖는다.
#1. Creation(Pre-parsing) Phase
Creation(Pre-parsing) Phase는 자바스크립트 엔진이 코드를 실행하기 전 먼저 변수와 함수의 선언을 분석하고 메모리에 적재하는 단계이다. 이 단계에서 변수와 함수는 선언되지만, 초기화는 실행 단계에서 이루어진다.
◼︎ 변수 선언 & 호이스팅
- var : 변수를 선언과 동시에 초기화. 초기화된 값은 undefined
- let & const : 변수 선언만 호이스팅. 초기화는 실제 코드에 도달했을 때 이루어지므로, 초기화 전에는 ReferenceError 발생
- 함수 선언도 호이스팅되며, 함수 전체가 메모리에 적재. 함수는 선언된 시점에 메모리에 등록되므로 선언 전에 호출 가능
호이스팅에 대한 더 자세한 내용은 아래 포스팅을 참고하면 된다.
https://itguswjd.tistory.com/206
[JavaScript] 호이스팅과 var/let/const 차이
01. JS 변수 선언 방법 : var / let / const자바스크립트에서 사용되는 변수 선언 방식에는 var, let, const 3가지가 있다.var는 ES6이전인 비교적 오래전부터 사용되었지만, ES6 등장 이후 현재는 잘 사용되지
itguswjd.tistory.com
◼︎ 함수 선언 & Lexical Scope
Lexical Scope는 함수가 선언된 시점의 환경을 참조하는 스코프이다.
따라서, 함수가 선언된 시점의 변수를 기억한다.
#2. Execution Phase
Execution Phase는 자바스크립트 엔진이 코드를 실제로 실행하는 단계이다.
이 단계에서 변수에 값이 할당되고, 함수가 실행된다.
◼︎ 변수 할당 & Scope Chain
실행 중에 변수가 선언된 위치를 확인하고, 변수에 값을 할당한다.
변수를 찾을 때 현재 스코프에서 변수가 없으면, 상위 스코프를 순차적으로 탐색한다. Scope Chain시 어디에도 없으면, Global내 선언 후 할당한다. let은 선언과 동시에 초기화되지 않기 때문에, 선언은 되었지만 초기화되어 있지 않아서 RefereceError가 발생한다.
◼︎ 함수 실행
함수가 실행되면, 함수 선언 시점의 렉시컬 환경을 기반으로 메모리 영역이 확보되며, 확보된 메모리 영역 내에서 함수가 실행된다.
💡 TDZ(Temporal Dead Zone)
TDZ는 let과 const가 호이스팅된 후 초기화되기 전까지의 시간 구간이다.
이 구간에서 해당 변수에 접근하면 ReferenceError가 발생한다.
#3. Lexical Scope / Scope Chain / Hoisting
◼︎ Lexical Scope
: 함수가 선언된 위치에 기반. 즉, 함수가 선언될 당시의 스코프가 결정되며, 호출되는 위치와는 무관
◼︎ Scope Chain
: 변수에 접근할 때, 현재 스코프에서 찾을 수 없는 경우 상위 스코프를 차례로 탐색( = Execution Phase 시 변수 선언이 안되어있을때, 호출 순서로 이전 실행 컨텍스트에서 검색)
: Global Execution Context 까지 다 찾아보았음에도 없을 시, 그 자리에 var 선언 및 할당
< Scope Chain 예시 >
🎯 name="nero" 인 경우
< 실행 과정 >
=> 실행 결과 "nero" 출력
🎯 var name="nero"인 경우
< 실행 과정 >
=> 실행 결과 : "zero" 출력
◼︎ Hoisting
: 자바스크립트 엔진이 코드 실행 전에 변수와 함수 선언을 메모리의 상단으로 끌어올리는 현상
'ASAC > Front-End' 카테고리의 다른 글