ES6를 사용하는 사람들에게 이는 기본 중의 기본이지만, 워낙 중요한 기본이니 한번 정리하고 넘어가자.
가장 큰 차이는?
모두 변수를 선언할 때 쓴다. 아래 작성한 것 외에도 차이가 있지만, 그것들은 뒤에서 다루도록 하겠다. 가장 큰 차이는 이렇다고 본다.
- scope의 차이 :
var
는 함수레벨,let
과const
는 블록레벨 스코프를 가진다. - 재할당의 차이 :
var
와let
은 재할당이 가능하지만const
는 재할당이 불가하다.
var의 특징
- 주로, ES6 이전까지 쓰여왔다.
- 함수의 블록만을 스코프로 인정한다. 이를
함수레벨 스코프
라고 부른다.(for문 내에서 선언한 변수는 for문 밖에서도 쓸 수 있다!) -
var를 생략 가능하다.(
var
를 안써도 된다)- 엄밀히 말하면, 생략했을 때와 생략하지 않았을 때가 똑같진 않다. 생략하게 되면 그 변수는 암묵적 전역(implicit global)이 된다.
- 변수 중복 선언이 허용된다.(
var
를 두번 써도 된다) - 변수 선언과 초기화에 대한 호이스팅이 발생한다.
- 참고로, var 키워드로 선언한 전역 변수는 전역 객체(Global Object) window의 프로퍼티이다.
let과 const의 특징
- ES6 이후부터는 주로 이들을 쓴다.
-
블록 모두를 스코프로 인정한다. 이를
블록레벨 스코프
라고 부른다.(for문 내에서 선언한 변수는 for문 밖에서는 쓸 수 없다!)- 참고로, if-else문은 중괄호가 있으므로 작성 당시부터 스코프가 있게 되지만 switch-case문은 case에서 중괄호를 안쓸 수 있으므로 스코프가 없는 걸로 인식될 수 있음을 참고하자. 즉, 각 case문 안에서, 같은 변수를 const로 각각 선언하면 변수 재할당으로 인식될 수 있다는 뜻이다.
- let이나 const는 생략할 수 없다.
- 변수 중복 선언은 불가능하다. 참고로, 이중에서
const
는 재할당이 불가하며 선언과 동시에 할당이 이루어져야 한다.(단, 아무리const
라고 해도, 변수 내 프로퍼티를 수정하는 것까지 금지되어있지는 않다. 해당 변수는 한 객체에 대한 ‘참조 값’만을 저장하고 있기 때문에, 그 참조 값이 변하지 않는 한도 내에서의 변화는 허용되기 때문이다!) - 변수 선언에 대해서만 호이스팅이 발생한다.(그래서
var
와 달리 TDZ가 발생하여 해당 변수를 미리 참조하지 못한다.)
정리
var
는 변수의 scope을 제어하기 어렵고, 비순수 함수에 의해 변경될 가능성이 있기 때문에 복잡성이 증가된다.(간단한 개발에서는 그다지 상관없다. 오히려 엄격하지 않아 편리할 수도…)- 이를 보완하기 위해 등장한
let
과const
를 주로 쓰도록 하자. - 굳이 비교하자면
let
보다const
가 엄격하여 재할당을 방지해준다. 따라서const
를 주로 쓰되, 재할당이 반드시 필요한 경우에 그때 가서let
으로 바꾸어도 늦지 않는다고 생각한다.