본문 바로가기
FE/Javascript

let, const, var

by ideal_string 2022. 9. 14.

자바스크립트를 배우다보면 자주 듣는 말중 하나가 자바스크립트는 자유로운(유연한) 언어라는 거다. 조금 더 나아가면 지멋대로인 언어라는 표현도 있다. 아무래도 C언어 같이 다른 언어에 비해 자료형을 정확히 기재하지 않아도 사용할 수 있기 때문이다. 이 중심에 var이 있었다. var은 ES5까지 주로 쓰였던 변수 선언인데, 자바스크립트를 자유롭게 하는 선언이면서 반대로 얽매는 선언이었다. 이를 보완하고자 나온 게 let과 const다. var, let, const를 하나씩 살펴보자.

var

var는 자바스크립트가 태어나 ES5까지 메인으로 쓰였다. 모든 선언은 전부 var이였기 때문. 함수든 클래스든 어디든 자바스크립트는 var 하나로 모든 변수 선언이 가능했다. 그러나 독특한 특징 때문에 발목을 잡히기도 한다. ES6에서 let과 const를 등장하게 한 var 특징을 보자.

 

특징

1. 호이스팅

var은 자바스크립트 내 어디에서 선언되든 최상단으로 끌어올려진다. 자바스크립트가 실행되자마자 var은 전역이라면 전역 제일 상단, 함수라면 함수 제일 상단으로 올려진다. 즉, 선언과 할당이 동시에 하단에 되었더라도 선언부가 최상단으로 끌어올려져 먼저 선언이 된다. 이때 초기값은 아무것도 없는 undefined 상태다. 

console.log(a)  //undefined

var a = 1;

console.log(a) // 1

일반적인 상황이라면 첫번째 출력에서 오류가 나야 정상이다. 자바스크립트도 인터프리터 언어, 즉 위에서부터 한줄씩 읽는 언어기 때문에 오류가 나야만 하는 상황임에도 오류가 아닌 undefined를 출력한다. 그리고 var가 선언된 줄을 지나 출력하니 원하던 할당했던 1이 출력됐다. 

var a;

console.log(a)  //undefined

a = 1;

console.log(a) // 1

var는 사실상 위 코드처럼 작동한다. 

 

2. 중복 선언

가장 개발자를 위험하게 하는 요소가 바로 이 중복 선언이다. var는 중복으로 선언할 수 있다.

var a = 1;
var a = "hello";
var a = 100;
var a = "world";

코드가 어딘가 어색하다. a를 무려 4번이나 선언했다. 할당 혹은 재할당도 아닌 새로 선언을 4번이나 했다. 오류? 없다. 위 코드를 출력한다면 인터프리터 언어인 만큼 맨 마지막에 있는 "world"만 출력한다. 코드가 짧으니 상관 없는 듯하다. 다만, 코드가 몇만줄이거나 여러 사람이 협업하는 코드라면 난감해질 수 있다. 시간 가는대로 개발하다가 어느날 변수 명을 사용했는데, 원치 않은 오류가 날 수 있다. 변수명이 중복 선언된지도 모르고 계속 엉뚱한 값을 양쪽에 덮어 씌웠기 때문이다.

 

3. 함수 스코프

var는 중괄호를 이따금 통과한다.

function asdf(){
  for (var i=0;i<5;i++){
  }
  console.log(i)
}

asdf() // 5

for문 안에 쓰인 i를 보자. var로 선언했다. for문이 끝난 후 i를 출력시도했더니, 아무 오류 없이 출력됐다. var은 함수 스코프기 때문이다. 같은 함수 안에 있다면 호이스팅되어 함수 최상단으로 올려진다.

 

let

ES6에서 처음 나온 선언이다. var을 보완하고자 나온 만큼 var와 다른 특징도 갖고 있다.

 

특징

1. 재선언 불가

let은 다시 선언할 수 없다. 재선언 시 이미 선언된 변수라고 오류가 뜬다.

let a = 1;
let a = "hello"; //Uncaught SyntaxError: Identifier 'a' has already been declared

 

2. 재할당 가능

재선언은 할 수 없지만, 재할당은 언제든지 얼마든지 가능하다.

let a = 1;
console.log(a); // 1
a = "hello"
console.log(a); // hello
a = null
console.log(a); // null
a = "world"
a = "12345"
a = true
console.log(a); // true

 

3. 블록 스코프

let은 자기가 속한 스코프 밖을 나갈 수 없다. 

function asdf(){
  for (let i=0;i<5;i++){
  }
  console.log(i)
}

asdf() // undefined

var에서 돌렸던 for문을 let으로 다시 돌렸다. 스코프를 통과하지 못한채 undefined 띄웠음을 확인할 수 있다.

const

let과 함께 공개됐다. var를 보완하고자 let과 함께 나온 만큼, let과 같은 특징과 다른 특징 모두 갖고 있다.

 

특징

1. 블록 스코프

let과 동일하게 블록 스코프다.

 

2. 초기 선언 필수

const는 상수 즉, 수식에서 변하지 않는 값을 선언한다. 따라서 초기 할당 없이 선언할 수 없다. 없는 값을 변경시킬 수 없을 뿐만 아니라, 애초에 없는 값이 없을 수도 없기 때문이다. 

const declare; //Uncaught SyntaxError: Missing initializer in const declaration

 

3. 재할당 불가

상수인 만큼 재할당도 할 수 없다. 변하지 않는 값을 변경한다면... 수학을 떠나 철학으로 떠나야 한다.

const asdf = 234; 
asdf=1; //Uncaught TypeError: Assignment to constant variable.

 

마무리

자바스크립트를 사용한다면 var는 지양해야 한다. var는 원치 않는 호이스팅, 재선언 등 언제 터질지 모르는 폭탄이라 여겨진다. 필자는 사전에 스코프 범위를 쉽게 인지할 수 let과 const만 있다고 생각할 예정이다. 재할당 해야하면 let, 값이 변하지 않아야 한다면 const 끝.

※ 잘못된 내용이 있을 경우 댓글로 알려주세요. 배우고 익히고 수정하겠습니다:)

'FE > Javascript' 카테고리의 다른 글

Primitive type & Reference type  (0) 2022.09.20
null & undefined  (0) 2022.09.15
Destructuring Assignment  (0) 2022.09.13
hoisting  (0) 2022.09.11
loop method - filter, map, every, some  (0) 2022.09.08