자바스크립트(JavaScript)의 변수는 임의의 값을 저장하고 필요한 곳에서 다시 사용하기 위해 사용되는 저장소입니다.
변수에는 여러 가지 유형이 있지만 그 중에서도 var, let, const는 가장 일반적으로 사용되는 변수 유형으로 오늘은 이 특징들에 대해서 알아보겠습니다.
Var
자바스크립트(JavaScript)의 가장 오래된 변수 유형입니다. var는 함수 스코프를 가지고 있습니다. var로 선언된 변수는 중복 선언이 가능하며, 변수 선언과 동시에 값을 할당할 수도 있습니다.
범위 또한 전역 범위 혹은 함수 내에서만 지정하여 자유롭게 사용이 가능합니다.
한번 예제를 살펴보겠습니다.
var kaheal_name_en = "kaheal"; // 값이 지정된 변수 선언
var kaheal_name_kr; // 값이 지정되지 않은 변수 선언
var kaheal_name; // 값이 지정되지 않은 변수 선언
function load() {
var kaheal_name_kr = "카힐"; // 함수 내에서의 변수 선언
console.log(kaheal_name_kr); // 카힐
kaheal_name = "전역 변수 카힐"; // 전역 변수 kaheal_name 에 값 지정
}
load();
console.log(kaheal_name_en); // kaheal
console.log(kaheal_name_kr); // undefined
console.log(kaheal_name); // 전역 변수 카힐
여기서 kaheal_name_en, kaheal_name_kr, kaheal_name을 전역 변수로 지정을 해주었습니다.
이처럼 초깃값의 유무와 상관없이 변수로 등록이 가능합니다.
이후 실행을 하여 load()를 걸치고 나면 kaheal_name_kr만 값이 넘어오지 않는 것을 보실 수 있습니다.
바로 load() 안에서 var를 사용하여 이 변수는 이 함수 내부에서만 사용하겠다고 선언을 해주었기 때문입니다.
반면에 var 가 없는 kaheal_name 은 정상적으로 값이 넘어온 것을 확인하실 수 있습니다.
Var의 문제점
이렇게 보면 문제점은 없어 보이지만 사실 var를 사용할 시 생기는 가장 큰 문제점(취약점)이 있습니다.
var kaheal_name = "카힐";
var kaheal_name = "카힐님"; // 재선언
var change = true;
if(change) {
var kaheal_name = "kaheal"; // 블록 내에서 변수 선언
console.log(kaheal_name); // kaheal
}
console.log(kaheal_name); // kaheal
현재 change가 true기 때문에 kaheal_name은 "kaheal"로 재정의 됩니다.
이런 부분이 의도적이라면 괜찮겠지만,
kaheal_name의 초깃값을 저장해두고 싶은데 이미 정의되어 있다는 사실을 몰랐다면?
함수 내에서 선언했을 때는 함수 내에서만 사용이 가능했는데, 왜 블록 내에서는 블록 내에서만 유지가 안되는 걸까?
이와 같은 생각과 뜻밖의 출력 결과에 놀랄 수밖에 없겠죠?
현재는 코드가 짧아서 쉽게 찾겠지만, 더더욱 길어지는 코드라면 어떨까요?
그래서 let과 const의 유형이 필요하게 된 것이죠.
Let
새로운 유형이라고 어렵게 생각하실 필요 없습니다.
다만, 존재했던 var 유형을 개선했다고 쉽게 생각하시면 됩니다.
또한 이제는 var 유형보다는 let 유형을 사용하기에 차이점을 꼭 인지해두시면 좋습니다.
Var과 Let의 차이점
var에서 사용한 문제점이였던 코드에서 유형을 let으로 변경해보겠습니다.
let kaheal_name = "카힐";
let change = true;
if(change) {
let kaheal_name = "kaheal"; // 블록 내에서 변수 선언
console.log(kaheal_name); // kaheal
}
console.log(kaheal_name); // 카힐
차이점이 보이시나요?
바로 마지막 결괏값이 처음 지정했던 그대로 유지가 되어 나타나는 것입니다.
var은 블록 내에서 변수 선언을 하면 해당 함수 내에서 모두 인식 되는 변수가 되어버리지만
let은 블록 내에서만 사용이 가능한 변수가 됩니다.
또한 앞선 var는 하단과 같이 재선언을 하여도 아무런 문제가 없었습니다.
var kaheal_name = "카힐";
var kaheal_name = "카힐님"; // 재선언
하지만 let 일 경우 이와 같은 에러가 발생합니다.
let kaheal_name = "카힐";
let kaheal_name = "카힐님"; // Error: Identifier 'kaheal_name' has already been declared
바로 let은 같은 블록 범위 내에서는 다시 선언이 불가능합니다.
만약 kaheal_name의 값을 변경하고 싶다면 이와 같이 정의를 해주면 에러가 발생하지 않습니다.
let kaheal_name = "카힐";
kaheal_name = "카힐님";
console.log(kaheal_name); // 카힐님
같은 블록에서는 이미 선언이 되어있으니, 다시 선언할 필요가 없는 것이죠!
만약 이와 var과 let은 초깃값이 변경이 가능했는데 초깃값이 아예 변경하고 싶지 않다면 어떨까요?
바로 const로 선언을 해주시면 됩니다.
Const
const는 let과 비슷한 성질을 가지고 있습니다.
다만 개체 업데이트를 하거나 다시 선언이 불가능하고 초깃값이 존재해야 한다는 것이죠.
하지만 특이하게 속성은 업데이트가 가능하다는 점입니다.
바로 이전과 동일한 코드들로 예제를 보면 이와 같은 에러가 발생합니다.
const kaheal_name; // Error: Missing initializer in const declaration
const kaheal_name = "카힐";
const kaheal_name = "카힐님"; // Error: Identifier 'kaheal_name' has already been declared
const kaheal_name = "카힐";
kaheal_name = "카힐님"; // Error: Assignment to constant variable.
첫 번째 코드는 값이 없다는 에러가 노출
두 번째 코드는 let과 동일하게 이미 선언이 되어있기에 불가능하다는 에러가 노출
세 번째 코드는 변경이 불가능하다는 에러가 노출.
속성 업데이트
앞서 말씀드린 것처럼 특이하게 개체는 업데이트가 불가능하지만, 속성은 업데이트가 가능합니다.
만약 이와 같이 프로필을 저장하는 변수를 지정했다고 가정합니다.
const profile = {
name: "카힐",
age: "18"
};
console.log(profile); // {name: '카힐', age: '18'}
제 나이가 18살이라니 말도 안 되죠?
그럼 속성 값은 변경이 가능하다고 하였으니, 나이를 32살로 변경해 보겠습니다.
그리고 직업도 추가하겠습니다.
const profile = {
name: "카힐",
age: "18"
};
profile = {
age: "32",
job: "프리랜서"
}; // Error : Assignment to constant variable.
하지만 이와 같이 업데이트가 불가능한 것을 보실 수 있습니다.
왜 속성은 업데이트가 가능하다고 했는데, 불가능한가요?
바로 변경하는 방식이 다르기 때문입니다.
이와 같이 개체 자체는 변경을 하지 않고, 속성에만 접근을 하여 수정을 하면 변경이 가능합니다.
const profile = {
name: "카힐",
age: "18"
};
profile.age = "32";
profile.job = "프리랜서";
console.log(profile); // {name: '카힐', age: '32', job: '프리랜서'}
차이점 요약
- var 선언은 전역 범위 또는 함수 범위, let과 const는 블록 범위
- var 선언은 업데이트 재선언이 가능하다.
let 선언은 업데이트만 가능하고 재선언이 불가능하다.
const 선언은 속성 업데이트만 가능하고 재선언은 불가능하다. - var 와 let 은 초깃값이 없이 선언이 가능하지만, const 는 초깃값을 선언해 줘야 한다.
생각보다 어려운 듯하지만 간단하죠?
이와 같이 변수 선언을 지정함으로써 개발 시의 문제점들을 빠르게 파악이 가능하고
생각하지 못한 오류를 미리 잡아낼 수가 있습니다.
이제 개발 시 let과 const를 사용해 볼까요?
제가 알고 생각하는 대로 작성을 했기에 혹시 추가할 내용이 있다면 알려주세요.
또한 질문이 있다면 언제든지 말씀해 주세요.
감사합니다 :)