var 키워드는 javascript 에서 변수 선언을 위해 사용되는 녀석이지만 여러가지 혼돈을 가져오기도 한다. var 키워드의 문제점과 es2015에서 소개된 let, const에 대해 알아보자.
let, const 키워드
var의 문제점과 let, const의 활용
var는 오랜동안 javascript에서 변수 선언에서 사용되는 키워드 였다. 지금도 대부분의 소스 코드에는 var를 이용한 변수 선언을 심심찮게 찾아볼 수 있다.
하지만 var 키워드를 이용해서 선언한 변수는 java등에서 사용되는 변수와 큰 차이점이 있는데 바로 스코프이다.일반적으로 로컬 변수의 스코프는 변수가 선언된 {}를 대상으로 하는데 var 변수는 그 변수가 선언된 함수를 scope로 한다.
let func = function () {
{
let a = 10;
const b = 20;
var c = 30;
console.log(a, b, c);
}
console.log(c); // {}를 벗어났지만 여전히 var 변수인 c는 사용 가능하다.
};
func();
위 예에서 살펴보듯이 a, b, c 3개의 변수가 func 내부의 {} 내에 선언되었고 당연히 활용 가능하지만 var 변수인 c는 {}를 넘어서 까지 활용이 가능함을 알 수 있다. 이는 프로그래밍에서 매우 헤깔리는 상황으로 let 변수는 선언된 {} 내에서만 사용이 가능하기 때문에 이런 혼동을 사전에 막을 수 있다.
var 변수 때문에 나왔던 애매한 상황들 - closure
javascript에는 var 변수 때문에 매우 이해하기 어려운 상황이 발생될 수 있다. 다음과 같은 button들에서 발생하는 click 이벤트를 처리해보자.
let buttons = document.querySelectorAll(".bad");
for (var btn of buttons) {
console.log(btn); // 버튼의 정보 확인
btn.addEventListener("click", function () {
console.log(btn.value);
});
}
dom에서 bad 클래스로 선언된 요소들을 가져와서 반복문에서 이벤트 리스너를 등록하는 코드이다. 이 스크립트를 실행해보면 버튼의 정보가 아래처럼 잘 출력되는 것을 볼 수 있다. 즉 버튼들은 순차적으로 잘 접근이 된다. 하지만 막상 버튼들을 클릭해보면 3번 버튼에 대한 정보만 출력되고 1번, 2번 버튼에 대한 정보는 유지되지 않았음을 알 수 있다.
왜 이런일이 발생했을 까? btn이 local 변수이므로 매번 변경될것 같지만 scope가 계속 이어지면서 function 내부에서는 마지막 버튼이 3번이 할당되기 때문이다.
이런 상황을 해결하기 위해서 closure를 사용한다.
// closure 이용
buttons = document.querySelectorAll(".good");
for (var btn of buttons) {
// 함수만의 스코프로 만들어줘서 독립적으로 동작하게 한다.
(function (nbtn) {
nbtn.addEventListener("click", function () {
console.log(nbtn.value);
});
})(btn);
}
즉 for 문 내부의 변수 btn을 내부에 있는 함수의 파라미터로 전달해서 해당 함수의 local 환경을 구성해버리는 것이다.
히자만 let 변수를 사용하면 애초에 이런 고민을 할 필요가 없어진다.
buttons = document.querySelectorAll(".bests");
// let 변수를 이용하면 간단해진다.
for (let btn of buttons) {
btn.addEventListener("click", function () {
console.log(btn.value);
});
}
이외에도 var 키워드는 변수의 중복 선언이 허용되서 부지불식간에 값이 초기화되는 경우가 있었지만 let은 변수의 중복 선언이 허용되지 않는다.
var a = 10;
var a = 20;
let b = 10;
//let b = 30; //Uncaught SyntaxError: Identifier 'b' has already been declared
상수의 선언은 const
ES6 이전의 JavaScript에서는 상수의 처리가 불가했지만 ES6에서 const가 생기면서 변하지 않는 값을 처리할 수 있게 되었다.
const c = 10;
//c = 20; // 01_let.html:104 Uncaught TypeError: Assignment to constant variable.