Adventure Time - Jake js의 변수 선언 방법(var, let, const)와 var, let의 차이 | 호이스팅|TDZ
본문 바로가기
Front-end/javascript

js의 변수 선언 방법(var, let, const)와 var, let의 차이 | 호이스팅|TDZ

by bogyoi 2024. 1. 3.

js에서 변수를 선언하는 방법에는 세가지가 있다. ( const, var, let)

 

const는 변수값을 고정시키고 싶을 때 사용한다.(값을 수정하려고 하면 error가 난다. )

 

C를 배웠다면 알다시피 C언어에도 const가 있다. 물론 추가적으로 #define이나 enum도 있겠다. 

C언어에서의 const와 js에서의 const는 의미 면에서는 비슷한 듯하다. 대개 읽기만 하는 값(read-only)이나 절대 변하면 안되는 값을 const로 선언하는 편. 참고로 const는 초기값 없이는 선언이 불가하다.

 

 

var: 선언 시 메모리에 담아둔다. (함수가 실행되기 전에 메모리에 담아뒀던 변수들을 스코프 범위(scope:변수가 적용되는 범위)의 최상단으로 끌어올린다.) 이런걸 호이스팅(hoisting)이라고 한다. 하지만 const와 let이 호이스팅이 안 일어난다는 뜻은 아니다. var은 함수 스코프로 호이스팅이 되었다면, const와 let은 블록 스코프로 호이스팅이 일어난다.

 그럼 왜 const와 let은 선언 전에 변수에 접근을 할 경우 error이 발생할까? const와 let은 TDZ가 발생하고, var는 발생하지 않기 때문이다. (TDZ(Temporal Dead Zone): 변수 선언 전에 변수에 접근하는 것을 금지하는 것). const와 let은 선언 구문을 만나기 전까지 TDZ에 있기 때문에 사용이 불가하고 호이스팅이 발생하지 않는 것처럼 보이는 것이다.

 그래서 보통 변수 선언도 전에 해당 변수를 호출하면 오류가 뜨는게 당연지사, 웬걸 js에서 var로 선언한 변수는 선언 전에 호출을 했어도 오류가 나지않는다. 물론 출력을 해보면 개발자가 설정한 값으로 나오진 않는다. 왜냐하면 변수를 선언하고 undefined 값으로 초기화를 시켜 올려놨을 뿐이고, 개발자가 설정한 값으로 초기화되는 일은 코드 실행 시 실행도구가 해당 코드를 만났을 때 실행되기 때문이다.

console.log(n)  //undefined
var n = 1
console.log(n)  //1

-> 변수 선언 전에 변수를 콘솔에 출력했을 때 오류가 나는게 아니라 undefined 값이 출력된다.

 

 

사실 var는 전역/지역 변수 면에서도 문제가 있다. 스코프 범위가 다르기 때문이다. 따라서 변수가 유효한 범위가 어디까지인지에 대해 주의가 필요하다.

for (var i=0; i<3; i++){
	console.log(i)  //0, 1, 2 출력
}
console.log(i)  //3 출력

-> for 문 안에서 쓰인 i가 for문 바깥에서 출력을 했음에도 살아있다.

var은 함수만 지역변수로 호이스팅이 되고, 그 외(for, if 등)의 함수 외부에서 선언된 것은 모두 전역변수로 올라간다. 즉, 함수 내부에서 지정됐을 때에만 지역변수로써 함수 내부에서만 사용이 가능하다.

그래서 전역 변수로 사용하려면 1.함수 밖에서 선언하거나, 2.함수 안이라면 var 예약어로 선언을 하면 안된다.

물론 변수를 사용할 때는 전역변수를 최대한 쓰지 않는 것이 좋다.(뜻밖의 오류가 발생할 수 있는 확률이 높아진다.)

 

 

var n = 1;
var n = 2; //재선언
n = 3; //재할당
//모두 오류 x

게다가!! var로 선언한 변수는 중복 선언을 해도 오류가 발생하지 않는다. (같은 변수명으로 재할당 및 재선언이 가능)

 

 

그래서 var 선언 방법은 코드 길이가 길어지다보면 뜻밖의 오류를 마주할 수 있는 잠재된 위험이 있다.

그래서 ES6버전부터 추가적으로 나온 변수 선언 방법이 바로 let 예약어이다.

 

 

let으로 선언 시 위에서 말한 문제들이 해결이 된다. 함수 레벨의 스코프를 가지는 var과 달리, 블록 레벨의 스코프를 가진다. 즉, let으로 선언한 변수는 블록({ })으로 묶은 부분에서만 유효하다.

let 예약어는 재선언이 불가하므로 같은 변수명으로 중복 사용하게 되는 문제가 없고,

만약 전역변수를 선언하고 싶다면 예약어 없이 변수 이름만 써서 선언을 하면 된다. 

 

 

아래는 const, var, let을 재할당/재선언 가능 여부와 스코프 레벨을 정리한 표이다.

  재할당 재선언 스코프
const x x 블록 레벨
var o o 함수 레벨
let o x 블록 레벨