본문 바로가기
자바스크립트 중급 강의

변수, 호이스팅, TDZ(Temporal Dead Zone) - 자바스크립트 중급 강좌 #1

2021. 10. 27.

자바스크립트 중급 강좌 #1 - 변수, 호이스팅, TDZ(Temporal Dead Zone)

 

변수의 생성 과정

변수는 선언-초기화-할당 단계를 거쳐 생성된다. (초기화: undefined를 할당해주는 단계)

var는 선언과 초기화가 동시에 일어나고, 그 뒤에 할당된다.

let은 선언, 초기화, 할당이 모두 분리되어 있다.

const는 선언, 초기화, 할당 모두가 한꺼번에 일어난다.

(let 과 var는 선언과 할당이 분리되어 있기 때문에 선언을 미리 해두고 나중에 할당하는 것이 가능하다. 그렇기 때문에 할당된 값을 바꿀 수도 있게 되는 것)

 

변수 var, let, const 비교

1. var 는 한번 선언된 변수를 다시 선언할 수 있다. 반면, let과 const는 안 됨.

2. var 로 선언한 변수는 선언 전에 사용할 수 있다. 반면, let과 const는 안 됨.

2-1. var 는 호이스팅 때문에 선언 전에 사용할 수 있다.

⇒ name 을 var 로 선언하기 전에 console.log를 사용했지만 error를 일으키지 않는다.

⇒ var로 선언한 변수는 코드가 최상위로 끌어올려진 것처럼 동작하기 때문이다.

undefined 인 이유 : 선언은 호이스팅 되지만, 할당은 호이스팅 되지 않기 때문이다.

(호이스팅: 스코프 내부 어디서든 변수 선언은 최상위에 선언된 것처럼 동작한다)

 

2-2. let, const는 tdz(temporal dead zone)의 영향을 받기 때문에 할당하기 전에는 사용 불가하다.

(호이스팅 된다, 안 된다의 문제가 원인이 아님을 주의할 것. var, let, const, function, class 등 자바스크립트의 선언 키워드들은 모두 호이스팅이 된다.)

이 코드는 에러 없이 30을 찍는다.

이 코드는 문제가 발생한다.

var의 경우, 선언과 초기화가 동시에 일어나기 때문에 호이스팅 시에 초기값이 없으면 자동으로 undefined로 초기화한다. 이때 메모리도 할당한다. 그러므로 호이스팅으로 변수가 선언되고 아직 값은 할당되지 않았지만 undefined를 초기값으로 하여 메모리가 할당된 상태이므로 에러가 발생하지 않는 것이다.

반면, let 과 const는 초기화가 자동으로 이루어지지 않는다. 그렇기 때문에 선언과 초기화 사이의 사각지대인 TDZ(Temporal Dead Zone)가 생기고 오류가 생긴다. let, const로 선언된 변수들은 TDZ 에서 호이스팅으로 선언만 되었을 뿐 어떤 메모리도 할당되지 않은 상태이다. 값을 초기화하는 코드 전까지는 TDZ 라는 사각지대인 것이고 그 시점에서 console.log 로 값을 참조하려고 하면 ReferenceError가 발생한다. (ReferenceError: Cannot access 'age' before initialization)

let, const 모두 변수 선언 코드 전까지가 TDZ 이지만 let의 경우 미리 선언만 하고 나중에 값을 할당하는 것도 가능하기 때문에 꼭 초기값을 할당하는 선언 코드가 아니어도 된다. 만약, 초기값을 할당하지 않고 변수 선언만 한다면 해당 코드 이후부터는 TDZ는 아니고 변수가 undefined로 초기화된 상태이다.

+) 호이스팅은 스코프 단위로 일어나고, 여기서 스코프는 함수 내부이다. 만약 호이스팅이 일어나지 않았다면 에러 없이 함수 바깥에서 선언한 30을 출력할텐데, 함수 내부에서 호이스팅이 일어나기 때문에 에러가 나는 것이다.

 

3. var, let 은 값을 다시 할당할 수 있지만 const는 한번 할당한 값은 변경할 수 없다.

4. var, let은 변수 선언 시 초기 값을 주지 않아도 되지만 const는 반드시 초기값을 할당해야 한다.

⇒ let과 var는 선언을 미리하고 나중에 할당하는 게 가능한데, const는 선언만 하려니까 error 가 난다. 선언 시에 할당도 해줘야 한다.

 

5. var 는 함수 스코프. let, const는 블록 스코프

5-1. var : 함수 스코프

⇒ 함수 내에서 선언된 변수만 지역변수가 된다.

그러므로, if 문 안에서 var로 선언된 변수는 if 문 밖에서 접근할 수 있다. 하지만 만약 txt를 var가 아닌 let이나 const로 선언한다면 if문 밖에서 사용할 수 없다. 왜냐하면 let과 const는 if 문과 같은 블록 내에서 선언된 변수는 블록 내부에서만 접근할 수 있고 블록 외부에서는 접근할 수 없기 때문이다.

var 는 함수 내에서 선언되면 함수 바깥에서 사용할 수 없다.

 

5-2. let, const: 블록 스코프 (함수, if 문, for문, while 문, try/catch문 등)

⇒ 코드 블록 내에서 선언된 변수는 블록 내부에서만 접근할 수 있고 블록 외부에선 접근할 수 없는 지역변수이다.

+) var 보다는 let과 const의 사용을 권장한다. 예측 가능한 결과를 내고 버그를 줄일 수 있기 때문.

 

댓글