우리가 프로그래밍을 하면, 무조건 쓸 수 밖에 없는 것이 있다. 함수? 콘솔? 등등....
많겠지만, 오늘 필자가 논의해 볼 주제는 이름하야. 변수라는 친구다.
이렇게 오잉? 할 수도 있지만, 그만큼 변수만큼 많이 쓰고, 중요한 개념도 없다고 생각한다. 그래서 이번 무지성 시리즈는 여태 한 번 변수 삼대장. let, var, const를 토대로 한 번 글을 끄적여 보겠다.
원래 자바스크립트에서는 변수를 선언하기 위해서는 var만 쓰였다. 하지만, es6 이후에 const와 let이 추가되었다. 그렇게 현재의 3대장이 구성되었다. 그렇다면, 모두가 알듯이 각각의 변수에는 다 문법적인 특징과 제약, 그리고 장단점이 모두 존재한다. 이에 대해 하나 하나씩 천천히 살펴보자.
Var 는 한 번 선언된 변수를 다시 선언할 수 있다. 이에 반해, let은 재선언이 불가하다. 또한, var는 선언하기전에 사용할 수 있다.
이를 우리가 흔히 알고 있는 호이스팅이라고 부른다.
하지만, 여기서 저기 언디파인드가 보이시는 가? 왜 언디파인드가 뜰까? 한 번 잠시 고민해 보자.
결국 이 문제의 원인을 보면, 선언은 호이스팅이 될 지언정, 할당은 호이스팅이 되지 않기 때문이다. 따라서 언디파인드가 뜨는 것이 당연하다.
사실 같은 상황이라면, 렛과 컨스트도 호이스팅은 된다.
그런데, 왜 var처럼 되지 않고 에러 처리가 나는 걸까?
이것은 Temporal Dead Zone
=> TDZ 때문이다.
이를 조금 더 자세히 한 번 살펴보자.
즉, 간단히 설명하자면, 다음처럼 name이라는 변수에 먼저 할당되기 전에는 절대 해당 변수를 사용할 수 없다.
즉, Tdz 영향에 있는 변수들은 사용이 불가하다. let과 const는 tdz의 영향을 받는다. 따라서 사용 불가하다. 이는 코드를 예측 가능하게 하고, 잠재적인 버그를 줄일 수 있다는 것으로 해석할 수도 있다.
자! 다음 두 가지의 코드를 한 번 살펴보고, 비교해 보도록 하자!
문제 없는 코드.
문제 있는 코드
여기서 많은 사람들의 오해가 발생한다.
대부분 이렇게 생각하는 경우가 많다.
렛은 호이스팅이 되지 않는다?
Nope! 호이스팅은 스코프 단위로 이뤄진다. 따라서, 스코프 내부가 tdz 영역이다.
보통 변수의 생성은 다음과 같은 3가지 과정으로 이뤄진다.
- 선언단계
- 초기화 단계
- 할당 단계
Let은 선언과 초기화 단계가 모두 분리 되어서 진행된다.
Let은 호이스팅 되면서 선언단계가 이뤄지지만, 초기화 단계는 실제 코드에 도달했을 때이므로, 레퍼런스 에러가 발생하게 된다.
콘스트는 선언과 할당이 동시에 되어야 한다.
렛과 바는 선언만 해주고 나중에 할당하는 것을 허용한다. 렛과 바는 값의 변경이 가능하므로 다음과 같은 당연하다.
하지만, const는 한 번 선언되면 값의 변경이 불가하다.
다음은 스코프. 즉, 변수가 미치는 범위다.
크게 바는 함수 스코프. 렛과 콘스트는 블록 스코프로 분류된다.
여기서 블록 스코프는 모든 코드 블록에서 선언된 변수는 코드 블록 내에서만 유효하며, 외부에서는 접근할 수가 없다는 것을 의미한다.
즉, 코드 블록 내부에서 지역 변수. 여기서 말하는 코드 블록은 함수, if문, for문 while문, try,catch문 등이다.
반면, 함수 스코프는 함수 내에서만 선언된 변수만을 의미하는 지역 변수다.
-> var는 이렇게 if문 밖에서도 사용 가능하다. 하지만, let과 const는 중괄호 내에서만 사용할 수 있다.
물론 var도 이렇게 함수 내에서 선언되면 밖에서 사용 불가하다. 유일하게 벗어날 수 없는 것이 함수 스코프다.
결론적으로는 바 대신에 렛과 콘스트 사용을 권장한다.
왜? 예측 가능하며 디버깅에도 훨씬 편하기 때문이다.
지금까지 변수의 삼대장을 토대로 변수의 성질에 대해 한 번 알아봤다. 간단한 정리만 해 봤지만, 핵심적인 부분만 한 번 언급해 봤다.
흔히 너무 자주 쓰다보니, 자연스레 무지성적으로도 쓴 것 같은데... 한 번 다시 생각해 볼 수 있는 계기가 되었으면 한다.
그럼 다시 또 무지성 타파하러 오겠다.