자바스크립트 엔진은 자바스크립트 파일을 실행한다고 생각하지만 사실 함수를 실행하고, 파일은 main함수인격
따라서 자바스크립트 엔진의 자바스크립트 파일 구동 방식은 자바스크립트 함수 구동 방식과 동일하다.
이에 자바스크립트 엔진의 자바스크립 함수 구동 방식에 대해 아래 간단히 2개의 Phase로 나누어 진행
- Creation(Pre-parsing) Phase: 실행에 앞서 어떤 변수와 함수가 정의되어있는지 먼저 분석
- Execution Phase: 그리고나서야 변수에 값을 할당하고, 함수는 실행
✅자바스크립트 엔진 구성: stack + heap
✅ 자바스크립트 엔진 내 함수 동작 원리
JS엔진은 Stack + Head 두개만 기억 = 자바스크립트 함수 동작 원리 이해도 마찬가지로 두개만 기억
- 함수 실행을 위한 메모리 영역 = 실행 컨텍스트 + 렉시컬 환경
- Stack: 실행 컨텍스트 = 함수 실행 환경(함수 실행 시 필요한 영역)
- Heap: 렉시컬 환경(Lexical Environment) = 변수/함수 저장소
- 심화: 원래는 아래 2개 구성인데, 쉬운 설명을 위해... 렉시컬 환경만 교육
- 렉시컬 환경(Lexical Environment) : let, const 변수 + 함수: Block-level
- let, const 는 Hoisting 발생 하지않음: 정확히는 발생이나 ReferenceError 에러
- 렉시컬 환경(Lexical Environment) : let, const 변수 + 함수: Block-level
- 심화: 원래는 아래 2개 구성인데, 쉬운 설명을 위해... 렉시컬 환경만 교육
💡hoisting: 선언부가 말려올라간다.
코드를 훑으면서 선언부를 메모리에 적어놓는다.
- var로 선언하면 변수가 위에 선언되든 아래에서 선언되든 상관없음. var변수: function level
- let, const는 상관있음.
creation phase와 execution phase 차이때문임. 아래에서 자세히 설명 예정
✅ 실행 컨텍스트
`프로그램`에 메모리와 CPU자원을 할당한 뒤 구동하면 `프로세스`라고 한다.
- 모든 함수의 구동은 그 함수 구동을 위한 메모리 영역을 확보한 것부터 시작
- 이때 자바스크립트에서 함수 구동을 위한 메모리 영역을 `실행 컨텍스트` 라고 부른다.
JS엔진 수행을 위한 최상위 실행 컨텍스트: global scope 혹은 global Execution context
타 프로그램에서도 모든 함수들이 수행되는 가장 메인 함수인 `main()` 함수같은 개념이라 생각하면 됨.
- 그래서 모든 프로그램의 시작은 `main()`메서드 혹은 함수의 stack에서 처음 시작한다.
Global Scope는 Global Object라는 전역객체를 갖고, 그곳에서 정의되는 함수들은 Global 메서드이다.
- 웹 서버(Node.js) 에서의 전역 객체는 = `global`
- 웹 브라우저(예, 크롬)에서의 전역 객체는 = `window`
✅ Creation(Pre-parsing) Phase: 함수(파일) 분석하며 메모리 내 변수 함수 적재
함수(파일) 분석하며 메모리(실행 컨텍스트, 렉시컬 환경) 내 변수, 함수 적재
변수 선언 & 함수 선언 = Declaration이 Creation Phase에서 발생한다.
변수 선언 + Hoisting
변수는 선언 -> 초기화 -> 할당 순으로 이루어진다.
변수를 선언 위치와 상관없이 변수에 값을 할당할 수 있다.
`var`는 선언과 동시에 초기화된다.
`const`와 `let`도 어김없이 변수 호이스팅이 된다. -> 변수 호이스팅되나, 초기화가 안되기 때문에 할당 및 사용시 에러 발생
`function` 도 함수 호이스팅 된다.
함수 선언 + Lexical Scope 박제
함수에서 변수 참조 시 함수가 선언된 시점(Lexing) 의 변수를 참조
✅ Execution Phase: 함수 실행을 위한 메모리 영역 확보 및 실행
함수 실행을 위해 먼저 메모리(실행 컨텍스트, 렉시컬 환경) 확보 후 실행
변수 할당 & 함수 실행이 Execution Phase에서 발생한다.
변수 할당 + Scope Chain
변수 할당 시 앞선 함수 호출지엔 선언이 없을까? 호출지 찾아나서기
- Scope chain을 따라서 함수 호출지를 찾아나선다. Scope Chain을 따라가다가 선언된 부분이 없으면 Global(웹 브라우저에서는 window) 내 선언 후 할당
- execution phase에서 `let`은 선언과 동시에 초기화되지 않기에, 호이스팅이 발생해도 할당 전에 초기화 안되어있어 오류
함수 실행
함수 실행 시 함수선언지로부터 연결된 메모리 영역을 확보 후 그 안에서 함수 실행
자바스크립트도 컴파일 한다는 사실
구글 V8엔진에서 함수가 실행될 때 -> Ignition 인터프리터 + TurboFan 최적화 컴파일을 통해 실행
[심화] TDZ (Temporal Dead Zone)
`let`, `const`의 ReferenceError가 일어나는 이유: TDZ
`let`, `const`도 결국 `var` 와 동일하게 변수 호이스팅이 발생하는데, 왜 ReferenceError가 발생하는지?
ReferenceError: Cannot access ? before initialization
`var` 와 `let`의 차이점
변수는 선언 -> 초기화 -> 할당 순으로 이루어진다.
`let`은 Complie Phase 끝나자마자 선언이 되었다 = 변수 호이스팅 발생
- 다시 말하지만 호이스팅은 선언부가 말려 올라가는 것이다. 아래에서 선언되었더라도 코드를 쫙 훑으면서 선언부를 미리 메모리에 적어놓음
`let`은 Excution Phase 진입하여 실행 시 초기화가 안되어있는데, 할당을 시도해서 에러 발생
- `var`와 `let`은 초기화 시점이 달라서 똑같이 변수 호이스팅이 발생해도 `let`은 변수 호이스팅이 발생되지 않은것 처럼 보이는것이다.
- `var`는 Complie Phase에서 선언 + 초기화
- 변수 호이스팅이 일어나고, undefined로 할당되어 있음(이해를 위해 초기화로 불렀다)
- `let`은 Execution Phase에서 초기화 또는 할당 수행
- 변수 호이스팅은 일어나지만 `var`와 달리 할당이 되어 있지 않음.
- 그래서 `let`의 경우 console.log로 아직 할당하지 않은 상태에서 호출하면 not assigned라고 표기
``변수는 선언과 할당으로 나뉘어져있다. 변수 호이스팅은 선언에 해당하는 것이며,
- `var`는 선언에 더해 undefined로 할당(초기화)을 미리 해놓는 것이고
- `let`, `const`는 선언만 할 뿐 undefined 할당(초기화)는 하지 않는다
'ASAC 웹 풀스택' 카테고리의 다른 글
React 의 특장점, 렌더 라이프사이클 및 Hook(1) - JSX문법 (0) | 2024.09.20 |
---|---|
자바스크립트 기본, 심화 문법 및 엔진 동작 원리(5) - 자바스크립트 객체 정의 및 사용 + 모듈 시스템 (2) | 2024.09.11 |
자바스크립트 기본, 심화 문법 및 엔진 동작 원리(2) - JS 변수, 함수 정의 및 사용 (0) | 2024.09.10 |
자바스크립트 기본, 심화 문법 및 엔진 동작 원리(1) - 함수형 프로그래밍 패러다임(순수함수, 얕은복사, 깊은복사) (1) | 2024.09.10 |
웹 저장소 및 HTTPS, CORS 보안(5) - CORS (0) | 2024.09.10 |