궁금점
호이스팅에 관해서 찾아보다 궁금한 점을 발견했습니다.
변수에 언제 접근하는지에 따라서 결과가 달라지는 것을 확인하였고, var을 제외하고 let과 const는 에러가 발생했습니다.
var
// case 1
console.log(foo);
var foo = 12;
// result
undefined
let
// case 2
console.log(foo);
let foo = 12;
//result
Cannot access 'foo' before initialization
const
// case 2
console.log(foo);
const foo = 12;
//result
Cannot access 'foo' before initialization
javascript variable lifecycle
javascript variable lifecycle은 3단계로 이루어져 있습니다.
- 선언 (Declaration phase)
- 초기화 (Initialization phase)
- 할당 (Assignment phase)
선언 단계
선언 단계는 변수를 scope에 등록하는 단계로, 해당 scope에서 변수를 찾을 수 있게 등록하는 단계입니다.
선언 단계는 코드에 변수를 선언하면 진행되는 단계로, javascript 엔진이 컴파일 할시 변수를 등록할 때 진행됩니다.
선언 단계에서는 해당 scope에 변수가 있는지는 알 수 있지만, 메모리가 할당되지 않은 상태입니다.
메모리가 할당되지 않았으므로 해당 상태의 변수에 접근 시 에러가 발생합니다.
초기화 단계
초기화 단계는 scope에 등록된 변수에 메모리를 할당하는 단계입니다.
각 변수들은 메모리를 할당받으면서 자동적으로 undefined값을 받게 됩니다.
초기화 단계까지 진행된 변수에 접근을 하면 undefined값을 얻을 수 있습니다.
할당 단계
할당 단계는 메모리가 할당된 변수에게 값을 넣어주는 단계입니다.
흔히 우리가 변수를 생성하고 초기값을 넣어주는 단계입니다.
Const, let, var lifecycle
Var
var의 lifecycle은 컴파일 시 선언 및 초기화가 진행되며, 런타임에 할당이 이루어집니다.
컴파일에서 선언 및 초기화가 진행되므로 메모리와 값(undefined)을 할당받습니다.
그 후 런타임에서 할당이 가능합니다.
따라서 컴파일 시 메모리를 할당 받으므로 scope에 var이 선언되어 있다면,
위치와 상관없이 호출이 가능해집니다.(코드에서 var선언이 뒤에 있더라도 호출은 가능, 값은 undefined)
let의 lifecycle은 컴파일시 선언, 런타임 시 초기화 및 할당을 합니다.
컴파일 시 선언만 진행되므로, 메모리 및 값이 할당되어있지 않습니다.
var처럼 코드 뒤에서 선언 후 실행 시 에러가 발생합니다(TDZ).
let은 초기화와 할당이 같이 이루어지지 않아도 되므로 메모리만 할당받을 수 있습니다.
이럴 경우 값은 undefined로 되어있습니다.
const의 lifecycle은 let과 비슷하게 컴파일시 선언, 런타임에 초기화 및 할당이 진행됩니다.
let과는 다른 점은 초기화와 함께 값을 할당해주어야 하는 것입니다.
const는 상수로 할당 후 값 변경이 되지 않습니다.
// without assign
const t;
console.log(t);
// result
Missing initializer in const declaration
// with assign
const t = 12;
console.log(t_;
//result
12
TDZ(Temporal Dead Zone)
TDZ은 scope의 시작부터(선언) 초기화 단계 전 까지를 말합니다.
즉 선언하여 scope에 변수로써 참조는 되나 초기화하지 못하여 메모리에 할당받지 못한 변수에 접근하여
ReferenceError을 발생시키는 구간을 의미합니다.
결론
- var: 선언만 하면 호출가능, 위치 상관없이 호출가능(같은 scope)
- let: 선언만 하면 호출가능, 단 코드상에서 먼저 선언해야만 호출 가능
- const: 선언과 동시에 초기화 해야 사용가능, 값 할당시 변경 불가능
참고자료
https://noogoonaa.tistory.com/78
https://ui.toast.com/weekly-pick/ko_20191014
사진출처
https://excellencetechnologies.in/blog/javascript-variable-scope-and-lifecycle/
# 2022-10-11 수정
'기록 > 궁금증' 카테고리의 다른 글
[Flask] Flask 객체 생성시 __name__은 왜 넣을까 (0) | 2022.10.05 |
---|---|
[Flask] Flask에 middleware을 넣어보자 (0) | 2022.08.23 |