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으로 바꾸어도 늦지 않는다고 생각한다.