해당 시리즈는 온라인 강의 사이트 '유데미'에서 클린코드 자바스크립트 강좌를 시청하고 작성하는 글입니다.
JavaScript에서 변수를 선언할 수 있는 키워드는 var
, let
, const
이렇게 3가지 방법이 있습니다. 이 중에서 let
과 const
는 ES2015
버전에 처음 등장한 친구들이어서 어쩔 수 없이 그 전까지는 var
예약어를 통해서만 변수를 만들 수 있었습니다.
이렇듯 let
과 const
는 var
의 단점을 보완하고 대체하기 위해 나온 키워드입니다. 하지만 예전에 작성된 코드들이나 습관적으로 작성된 코드들을 살펴보면 아직도 var
은 종종 보이기도 합니다!
그럼
var
그리고let
,const
의 차이점은 무엇일까요?
우선 var
은 함수 단위 스코프를 가지고, let
과 const
는 블록 단위 스코프를 가진다는 점이 가장 큰 차이점이라고 말할 수 있습니다.
스코프(scope)는 변수에 접근할 수 있는 범위를 말합니다.
그리고 스코프는 크게 전역 스코프와 지역 스코프로 나눌 수 있습니다.
전역 스코프(global)는 어디에서든 해당 변수에 접근 가능한 걸 의미합니다. (전역변수)
지역 스코프(local)의 경우, 한정적인 범위에서 해당 변수에 접근이 가능합니다. (지역변수)
그리고 위에서 설명한 함수 스코프, 블록 스코프는 모두 지역 스코프에 해당합니다.
var
A
를 호출하면 undefined
에러가 뜹니다.function Test() {
var A = '1'; // 함수 내부에서 선언
}
console.log(A); // Uncaught ReferenceError: A is not defined
var A = '1';
console.log(A); // 1
var
은 함수 내에서만 지역 변수로 유지되기 때문에, 아래 코드에서는 전역 변수로 취급됩니다.if (true) {
var A = '1';
}
console.log(A); // 1
let
, const
{}
내부에서 선언된 변수는 해당 블록에서만 접근 가능하다는 걸 의미합니다.function test() {
for (var i=0; i<10; i++) {
...
}
console.log(i) // 접근 가능
}
test(); // 10
var
의 경우 함수 스코프를 따르므로, 함수 내부에서는 변수 접근이 가능합니다.function test() {
for (let i=0; i<10; i++) {
...
}
console.log(i) // 블록 바깥에서 접근 불가능
}
test(); // Uncaught ReferenceError: i is not defined
let
, const
는 블록 스코프를 따르므로 블록 바깥에서는 변수 접근이 불가능해서 오류가 나옵니다.위에서 설명한 것처럼 var
과 let
, const
는 함수 스코프와 블록 스코프라는 큰 차이점이 있습니다. 하지만 그 외에도 차이점은 또 있습니다! 바로 선언과 할당의 방법입니다.
var A = '1';
console.log(A); // 1
var A = '2'; // 변수의 재선언 가능
console.log(A); // 2
A = '3'; // 변수의 재할당 가능
console.log(A); // 3
우선 var
는 변수의 재선언과 재할당이 가능합니다. 예시와 같이 마지막에 할당된 값이 변수에 저장되는 것을 볼 수 있습니다.
let A = '1';
console.log(A); // 1
let A = '2'; // 변수의 재선언 불가능
console.log(A); // Uncaught SyntaxError: Identifier 'A' has already been declared
A = '3'; // 변수의 재할당 가능
console.log(A); // 3
let
은 var
와 다르게 변수를 재선언할 시 해당 변수가 이미 선언되었다는 에러 메시지가 출력됩니다. 하지만 변수 선언 및 초기화 이후 반복해서 다른 값을 재할당할 수는 있습니다
const A = '1';
console.log(A); // 1
const A = '2'; // 변수의 재선언 불가능
console.log(A); // Uncaught SyntaxError: Identifier 'A' has already been declared
A = '3'; // 변수의 재할당 불가능
console.log(A); // Uncaught SyntaxError: Identifier 'A' has already been declared
function func() {
const list = ["A", "B", "C"]
list = "D";
console.log(list);
// TypeError: Assignment to constant variable
list.push("D");
console.log(list); // ["A", "B", "C", "D"]
}
const
는 constant(상수)를 뜻하기 때문에 한 번만 선언이 가능하며 값을 재할당하는 것도 불가능합니다.
하지만 위 예제와 같이 배열과 오브젝트의 값을 변경하는 것은 가능합니다.
var
, let
, const
각각의 특징을 알아봤습니다. 그러면 왜 var
의 사용을 지양하고 let
과 const
를 사용해야 할까요?
var
는 위에서 확인했듯이 중복 선언과 재할당이 굉장히 자유로운 선언 방식입니다. 이런 특성은 간단한 코드나 짧은 코드에서는 큰 문제가 없겠지만 코드가 길어지면 길어질수록 오류가 나올 확률이 높아집니다.
이미 선언했던 변수명을 모르고 또 사용할 경우, 기존에 있던 변수는 전혀 다른 값을 가지게 됩니다. 그 경우, 그 변수를 사용하는 다양한 로직들에 치명적인 문제가 생깁니다.
그러면 왜 유독 var
에서 이런 현상이 나타나는 것일까요?
그 이유는 바로 Hosting(호이스팅) 때문입니다.
그렇다면 호이스팅이란 무엇일까요?
간단하게 말하자면 선언과 할당이 분리된 것을 뜻합니다.
console.log(num); // undefined
var num; // 선언
num = 6; // 초기화
간단한 코드를 예시로 보여주면 위에 코드는 호이스팅을 거쳐서
실제로는 아래 코드처럼 작동하게 됩니다.
var num; // 호이스팅으로 인해 선언은 최상단으로 이동
console.log(num); // 호이스팅한 var 선언으로 인해 undefined 출력
num = 6; // 초기화는 호이스팅이 적용되지 않아서 최상단으로 이동하지 않습니다.
이렇듯 var
로 선언한 변수의 경우 호이스팅 시 undefined로 변수를 초기화합니다. 반면 let
과 const
로 선언한 변수의 경우 호이스팅 시 변수를 초기화하지 않습니다.
또한 호이스팅은 변수 말고도 함수도 똑같이 호이스팅 된답니다!
호이스팅이란 런타임시에 선언을 코드의 최상단으로 끌어올려 주는 것.
문제는 코드를 작성할 때 예상치 못한 실행 결과가 노출될 수 있다는 점입니다.
이를 방지하기 위해서var
를 지양하고let
과const
를 습관화합니다.
일단 var
를 지양하고 let
과 const
를 쓰는 방법이 제일 쉬운 방법이겠죠?!
그리고 또 다른 방법은 const를 사용한 함수 표현식을 사용하는 것입니다.
console.log(sum); //Uncaught ReferenceError: Cannot access 'sum' before initialization
const sum = function() {
return 1 + 2
};
위 코드는 const를 사용한 함수 표현식을 간단하게 작성한 코드입니다.
const
를 사용한 덕분에 이렇게 에러를 쉽게 찾을 수 있습니다.
이렇듯 익명 함수를 하나 만들어서 변수에 할당하는 것을 함수 표현식이라고 합니다!