
해당 시리즈는 온라인 강의 사이트 '유데미'에서 클린코드 자바스크립트 강좌를 시청하고 작성하는 글입니다.
JavaScript에서 변수를 선언할 수 있는 키워드는 var, let, const 이렇게 3가지 방법이 있습니다. 이 중에서 let과 const는 ES2015 버전에 처음 등장한 친구들이어서 어쩔 수 없이 그 전까지는 var 예약어를 통해서만 변수를 만들 수 있었습니다.
이렇듯 let과 const는 var의 단점을 보완하고 대체하기 위해 나온 키워드입니다. 하지만 예전에 작성된 코드들이나 습관적으로 작성된 코드들을 살펴보면 아직도 var은 종종 보이기도 합니다!
그럼
var그리고let,const의 차이점은 무엇일까요?
우선 var은 함수 단위 스코프를 가지고, let과 const는 블록 단위 스코프를 가진다는 점이 가장 큰 차이점이라고 말할 수 있습니다.
스코프(scope)는 변수에 접근할 수 있는 범위를 말합니다.
그리고 스코프는 크게 전역 스코프와 지역 스코프로 나눌 수 있습니다.
전역 스코프(global)는 어디에서든 해당 변수에 접근 가능한 걸 의미합니다. (전역변수)
지역 스코프(local)의 경우, 한정적인 범위에서 해당 변수에 접근이 가능합니다. (지역변수)
그리고 위에서 설명한 함수 스코프, 블록 스코프는 모두 지역 스코프에 해당합니다.
varA를 호출하면 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); // 1let, const{} 내부에서 선언된 변수는 해당 블록에서만 접근 가능하다는 걸 의미합니다.function test() {
for (var i=0; i<10; i++) {
...
}
console.log(i) // 접근 가능
}
test(); // 10var의 경우 함수 스코프를 따르므로, 함수 내부에서는 변수 접근이 가능합니다.function test() {
for (let i=0; i<10; i++) {
...
}
console.log(i) // 블록 바깥에서 접근 불가능
}
test(); // Uncaught ReferenceError: i is not definedlet, 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를 사용한 덕분에 이렇게 에러를 쉽게 찾을 수 있습니다.
이렇듯 익명 함수를 하나 만들어서 변수에 할당하는 것을 함수 표현식이라고 합니다!