모든 프로그래밍 언어가 그렇듯 어떤 데이터를 저장하고 관리하며 앱을 구현한다.이번 게시글에선 javascript에서 변수를 선언하는 방법 중 var, let, const의 특징과 차이점에 대해 정리해본다.
기존의 javascript에서 변수 선언은 var로 할당하여 사용하였다.하지만 기존 var의 경우 스코프에 대한 기준, 중복 선언 등 문제가 많았다. 그러고 보면 지금까지 잘도 해먹었다. 이를 개선하기 위해 ES6가 업데이트되고 변수 선언방식 추가되었는데 그것이 let과 const이다.
var와 let, const는 다음과 같은 차이를 갖는다.
var의 경우 같은 변수 명으로 중복 선언이 가능하다. 이것부터가 얼마나 기준이 러프한 선언방식인지 알 수 있다. 하지만 let과 const의 경우 중복된 이름을 사용할 경우 다음과 같은 오류를 발생시킨다.
var a = 0;
console.log(a); // 0
var a = 20;
console.log(a); // 20
// let 중복 선언
let a = 0;
let a = 10; // SyntaxError: Identifier 'a' has already been declared
// const 중복 선언
const b = 0;
const b = 10; // SyntaxError: Identifier 'b' has already been declared
변수를 사용하다 보면 그 변수의 값을 재할당할 경우가 생긴다. var와 let은 가능하지만 const는 상수 키워드기 때문에 const는 초기화시 값을 할당해 주어야한다.
var a = 0;
a = 20;
console.log(a); // 20
let b = 0;
b = 10;
console.log(b); // 10
const c = 0;
c = 30; // TypeError: Assignment to constant variable.
스코프란 변수를 참조할 수 있는 범위를 말한다. javascript에서도 변수의 유효 범위가 존재하는데 let/const보다 var의 선언 범위가 러프하다. 다음 예제를 보자
var의 경우 함수 내부에서 선언한 변수만 지역변수 처리하는 아주 단순한 선언방식이다.
const fn = () => {
var a = 10;
console.log(a);
}
fn(); // 10
console.log(a); //ReferenceError: a is not defined
해당 코드를 실행시키면 된다;;
if (true) {
var a = 10;
console.log(a); // 10
}
console.log(a); // 10
let/const의 경우 if, for문 {}로 묶이는 제어문 내부에서 선언된 변수도 지역 변수 처리된다.그렇기 때문에 블록 레벨 스코프를 지원한다라고 말할 수 있다.
if (true) {
let a = 10;
const b = 20;
console.log(a); // 10
console.log(b); // 20
}
console.log(a); // ReferenceError: a is not defined
console.log(b); // ReferenceError: b is not defined
javascript에서 변수를 선언할때 내부적으로 3가지 작업이 수행된다.1. 선언 : 변수를 상단에 옮겨 등록한다.2. 초기화 : 등록 된 변수객체에 대한 메모리를 할당한다. 값은 undefined3. 할당 : 초기화 된 변수에 지정된 값을 할당한다.
var 변수의 호이스팅이 일어나는 과정은 다음과 같다.
console.log(a); // undefined
var a = 10;
위 코드를 내부적으로 실행되는 순서로 바꿔본다면 다음과 같다.
var a;
console.log(a); // undefined
a = 10;
// 이후 a값을 console로 찍어볼 경우 10을 출력하는 것을 확인할 수 있다.
console.log(a); // 10
다음과 같은 경우에는 오류가 발생해야 하는 것이 맞다. 하지만 이런 코드를 가능하게 해주는 것이 바로 호이스팅이다.
다음은 let/const로 선언된 변수를 보자
console.log(a); // ReferenceError: Cannot access 'a' before initialization
let a = 10;
오류가 발생한다.
var와 호이스팅이 일어나는 과정이 다를 뿐이다. 다음 코드를 보면 알 수 있다.
let a = 10; // 전역변수 a선언
if (true) {
console.log(a); // ReferenceError: Cannot access 'a' before initialization
let a = 0; // 지역변수 a 선언
}
전역으로 선언한 변수 a가 있음에도 오류가 발생한다. 이유는 let/const의 경우 블록 레벨 스코프이기 때문에 if문 내부에서 지역변수로 초기화가 발생한다. 그렇기 때문에 위와 같은 결과가 출력된다. 다음과 같이 실행된다고 이해하면 된다.
let a = 10; // 전역변수 a선언
if (true) {
let a;
console.log(a); // ReferenceError: Cannot access 'a' before initialization
a = 0; // 지역변수 a 선언
}
결론적으로 var와 let/const의 호이스팅 방식의 차이는 변수 할당에 있다.var 변수의 경우 선언과 동시에 초기화가 일어나기 때문에 오류가 아니라 undefined가 출력되는 반면 let/const의 경우 선언만 수행하고 실제 코드에서 초기화, 할당이 같이 수행된다. let/const는 초기화가 되지않았기 때문에 undefined도 아닌 것이다.
특정한 상황이 아니라면 변경이 없는 상수는 const, 이외 데이터는 let을 사용하여 선언하는 것이 바람직하다. 내가 알던 프로그래밍에 더 가까운 선언방식은 let, const다.
오늘 저녁은 삼겹살 덮밥이다. 🥕