궁금점

 

호이스팅에 관해서 찾아보다 궁금한 점을 발견했습니다.

변수에 언제 접근하는지에 따라서 결과가 달라지는 것을 확인하였고, 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단계로 이루어져 있습니다.

 

  1. 선언 (Declaration phase)
  2. 초기화 (Initialization phase)
  3. 할당 (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 수정