✍️ 호이스팅과 TDZ는 무엇일까?
🤜 스코프 구분
- 전역 스코프 (Global scope) : 코드 어디에서든지 참조할 수 있다
- 지역 스코프 (Local scope or Function-level scope)
: 함수 코드 블록이 만든 스코프로 함수 자신과 하위 함수에서만 참조할 수 있다
모든 변수는 스코프를 갖는다.
🤜 변수의 관점에서 스코프를 구분
- 전역 변수 (Global variable) : 전역에서 선언된 변수이며 어디에든 참조할 수 있다
- 지역 변수 (Local variable)
: 지역(함수) 내에서 선언된 변수이며 그 지역과 그 지역의 하부 지역에서만 참조할 수 있다
변수는 선언 위치(전역 또는 지역)에 의해 스코프를 가지게 된다
즉, 전역에서 선언된 변수는 전역 스코프를 갖는 전역 변수이고,
지역(자바스크립트의 경우 함수 내부)에서 선언된 변수는 지역 스코프를 갖는 지역 변수가 된다
👉 전역 스코프를 갖는 전역 변수는 전역(코드 어디서든지)에서 참조할 수 있다.
지역(함수 내부)에서 선언된 지역 변수는 그 지역과 그 지역의 하부 지역에서만 참조할 수 있다
🤜 스코프의 주요 규칙
1. 안쪽 스코프에서 바깥쪽 스코프로 접근할 수 있지만 반대는 불가능하다.
바깥쪽 스코프에서 선언한 식별자는 안쪽 스코프에서 사용 가능하다.
반면, 안쪽에서 선언한 식별자는 바깥쪽 스코프에서는 사용할 수 없다.
2. 스코프는 중첩이 가능하다. 스코프는 마치 중첩된 울타리와도 같다.
3. 전역 스코프와 지역 스코프
가장 바깥쪽의 스코프를 전역 스코프(Global Scope)라고 부른다.
전역이 아닌 다른 스코프는 전부 지역 스코프(Local Scope)이다.
4. 지역 변수는 전역 변수보다 우선순위가 더 높다.
전역 스코프에서 선언한 변수는 전역 변수, 지역 스코프에서 선언한 변수는 지역 변수이다.
지역 변수는 전역 변수보다 더 높은 우선순위를 가진다.
👉 화살표 함수는 블록 스코프로 취급한다
🤜 스코프와 var, let, const 키워드
- const 키워드
유효 범위 : 블록 스코프 / 함수 스코프
값 재할당 : 불가능
재선언 : 불가능
- let 키워드
유효 범위 : 블록 스코프 / 함수 스코프
값 재할당 : 가능
재선언 : 불가능
- var 키워드
유효 범위 : 함수 스코프
값 재할당 : 가능
재선언 : 가능
여러 스코프에서 동일한 식별자를 선언한 경우, 무조건 스코프 체인 상에서 가장 먼저 검색된 식별자에만 접근이 가능
즉, 직접적으로 변경되면 안되는 변수에 대한 접근을 막는것
이렇게 a와 b라는 클로저를 생성하면 함수 내부적으로 접근이 가능
🤜 함수 선언식과 함수표현식의 차이
- 주요 차이점 : 호이스팅에서 차이가 발생.
- 함수 선언식 : 함수 전체를 호이스팅
정의된 범위의 맨 위로 호이스팅되서 함수 선언 전에 함수를 사용할 수 있다는 것
- 함수 표현식 : 별도의 변수에 할당하게 되고, 변수는 선언부와 할당부를 나누어 호이스팅
선언부만 호이스팅하게 됨
🤜 Javascript 의 변수 생성 단계
1. 코드를 선언 단계(Declaration phase) : 변수를 실행 컨텍스트의 변수 객체에 등록하는 단계
2. 초기화 단계(Initialization phase) : 실행 컨텍스트에 등록한 변수를 위한 메모리를 만드는 단계
메모리가 만들어지면 처음에는 undefined 가 할당
3. 할당 단계(Assignment phase) : 사용자가 undefined 로 할당된 변수에 다른 값을 할당하는 단계
* var 는 선언과 초기화 단계가 동시에 이루어짐
* let, const 는 선언, 초기화, 할당 단계가 각각 따로 이루어짐
* function (함수 선언문) 은 선언, 초기화, 할당 단계가 동시에 이루어짐
👉 선언과 초기화 단계가 따로 이루어 지는 let, const 같은 경우는 TDZ에 영향을 받을 수 밖에 없다
🤜 TDZ에 영향을 받는 것
- let, const, class
- class의 constructor() 내부의 super()
(클래스의 contructor에서 super함수가 호출되기 전까지 클래스에서 this를 참조하면 에러 발생)
- 함수 매개변수 (매개변수 선언 전에 참조하면 에러 발생)
🤜 TDZ에 영향을 받지않는 것
- var, function (함수 선언식), import (import 구문)
전역컨텍스트 (Global Execution context)
: 자바스크립트 엔진이 코드를 실행할 때 처음으로 생성되는 실행 컨텍스트
- 아무런 코드가 없어도 두 가지 요소를 가진다.
1) global object
2) this (브라우저: Window, Node: global)
생성단계
- global object 생성
- this변수 object 생성
- 변수와 함수를 위한 메모리공간 확보
- 변수 선언 부분에 undefined(기본값)로 초기화, 선언식 함수를 메모리 공간에 올림
- 실행단계 (실질적으로 자바스크립트 엔진이 코드를 한 줄씩 읽고 실행하는 단계)
엔진이 코드를 한 줄씩 실 👉 실제 값을 메모리 공간에 저장
함수실행컨텍스트 (Function Execution context)
: 함수가 호출될 때마다 생성되는 컨텍스트
생성단계
- argument object 생성(🔥글로벌 실행컨텍스트와의 차이점, global object 아님🔥)
- this 변수 object 생성
- 변수와 함수를 위한 메모리 공간 확보
- 변수 선언 부분에 undefined로 초기화, 선언식 함수를 메모리 공간에 올림
- 함수 실행컨텍스트는 함수가 호출되면 실행 스택에 쌓였다가, 실행을 마치면 콜스택에서 제거됨
- 함수호출 👉 새로운 함수 실행 컨텍스트가 콜스택에 쌓임 👉 생성단계
👉 실행단계 👉 콜스택에서 제거
1. 엔진이 처음 script를 실행할 때, Global Execution Context를 생성하고
이를 Call Stack에 push한다.
-
2. 엔진이 함수를 호출할 때 마다 함수를 위한 Execution Context를 생성하고
이를 Call Stack에 push 한다.
3. 자바스크립트 엔진은 Call Stack의 Top에 위치한 함수를 실행하며
함수가 종료되면 stack에서 제거(pop)하고 제어를 다음 Top에 위치한 함수로 이동한다.
👉 요약 : 프로그램이 함수 호출을 추적할때 사용