자바스크립트에서 변수를 사용할 때 우리는 var, let, const를 사용한다.
사용은 하지만 정확히 왜 var 대신 let, const를 사용하는지
var에는 어떤 문제점이 있었기에 ES6에서 let과 const를 발표했고
두 키워드를 사용하라고 ECMA에서 권장하고 있을까?
오늘 포스팅을 통해서 확실하게 정리하고 넘어가보자.
ES6에서 let, const가 등장하기 이전까지 자바스크립트를 활용해 변수를 선언하고자 할 때 var 키워드를 통해새서 변수를 선언하고 사용했었다.
var a = 0;
console.log(a); //output : 0
근데 var 변수에는 여러가지 골치거리가 있었다. 바로 호이스팅과 스코프 그리고 선언에 관련된 골치거리이다.
console.log(b); //선언하지 않았지만 호이스팅으로 인해 undefined
var b = 1;
위 코드를 살펴보면 Java를 공부한 사람들은 이렇게 생각 할 것이다.
"변수를 선언하지 않고 사용하겠다고? 무조건 에러가 뜨겠지."
하지만 정답은 undefined이다. b 라는 변수를 선언하지 않은채 console로 확인해 봤을 때 출력되는 결과물이다.
var temp = 0;
console.log(temp); //output : 0
var temp = 'final';
console.log(temp); //output: final
위 코드를 살펴보면 잘못된 코드라는 느낌이 올 것이다. 하지만 var 키워드는 이를 혀용한다. 세 번째 라인의 temp는 변수가 재선언이 되는것이다. 네 번째 라인에서 temp를 출력해볼 시 final이 출력된다.
그렇다면 이유를 알아보자
호이스팅이란 자바스크립트가 실행될 때 자바스크립트 엔진으로 인해서 선언된 변수, 함수 들이 최상단으로 끌어올려지는 것을 말한다.
그렇다면 호이스팅 될 때 변수를 끌고온다고 했는데, 왜 값은 undefined 로 출력되는 걸까? 그 이유는 변수가 호이스팅 될 때 선언된 변수를 가져오는 것이지 할당된 값까지 끌고오지 않기 때문이다.
** 변수의 선언이 함수의 선어보다 더 위로 올려진다.
변수는 선언된 위치에 따라서 유효한 범위를 가지고 있다. 예컨대 블록 { } 안에 선언된 변수 (제어문, 함수 등..)는 블록 스코프를 가지고 있고 블록 밖에서 선언된 변수는 전역 스코프를 가지고 있다. 블록 스코프를 가지고 있는 변수는 블록 안에서만 사용이 가능하고, 전역 스코프를 가지고 있는 변수는 블록 밖, 블록 안 스크립트 어디에서나 사용이 가능하다.
함수 레벨 스코프는 함수 내에서 선언된 변수는 지역변수이고 함수 밖에서 선언된 변수는 모두 전역변수 취급을 한다.
그럼 var 키워드는 스코프에서 어떤 문제점이 있을까?
그것은 바로 var 키워드는 함수 레벨 스코프라는 것이다.
//함수내 선언된 지역변수는 예외적으로 적용
function test() {
var c = 0;
}
console.log(c); //error (함수 내에서 선언된 변수)
//지역변수로 선언했지만 블록 밖에서 참조가 되는 문제점
for (var i = 0; i < 4; i++) {
}
console.log(i); //output : 4 (제어문 안에서 선언된 변수지만 밖에서 사용가능)
함수내에 선언된 변수는 당연히 함수 밖에서 사용이 될 수 없지만,
제어문 안에서 선언된 변수는 전역 변수 취급을 하여 블록 밖에서 사용해도 값이 출력이 된다.
이게 바로 var 키워드가 가진 문제점이다.
이런 문제점이 있기에 ES6 문법에서 let, const 키워드가 등장하였다.
그럼 이 키워드들이 각각 var의 어떤 문제를 해결해주는지 살펴보자.
let d = 0;
console.log(`d: ${d}`); // output : 0
일단 let 키워드를 활용해 변수를 선언하였다.
정상적으로 선언된 변수이기에 에러없이 잘 출력된다.
그렇다면 var에서 문제점으로 지적된 hoisting에 대한 내용을 테스트해보자
console.log(e); //error
let e = 0;
위 코드를 실행했을 시 콘솔창에 에러가 출력된다.
에러 내용은 e라는 변수가 선언이 안되었다 라는 것이다.
let,const 키워드는 var 키워드와 마찬가지로 호이스팅이 된다. 하지만 var키워드와 다르게 선언 이전에 참조를 하려면 Reference Error가 뜬다. 이는 let과 const 키워드는 호이스팅이 되지만 TDZ (Temperal Dead Zone) 에 의해 관리된다는 것이다.
//error : 이미 선언된 변수의 이름으로 변수 선언 불가
let e = 1;
또한 한번 선언된 변수를 다시 선언할 수 없다. (var 키워드는 가능하다)
e = 4;
console.log(`e: ${e}`);
이렇게 값을 재할당은 가능하다.
let 키워드를 살펴봤으니 const 키워드를 살펴보자.
const 키워드는 변하지 않는 값을 할당하는데 사용되는 키워드다.
상수 (constant) 라고 생각하면 이해가 빠를것이다.
const con; //error : const 키워드는 선언과 할당을 분리할 수 없다.
const con = 'final';
console.log(`con: ${con}`); //output : final
const con = 'project'; //error : const 재선언 불가
con = 'final project'; //error : const는 값 재할당도 불가능
마지막으로 let의 스코프에 대해서 살펴보자.
let a = 'final';
//test가 a보다 먼저 사용될 시 에러 (let이 선언되기 이전에 사용하려 했기 때문)
test(); //함수의 호이스팅 적용
function test() {
let b = 0;
console.log(a); //output : final
console.log(b); //output : 0
}
console.log(b); //error : b는 블록 스코프를 지닌 변수
for (let i = 0; i < 3; i++);
console.log(i); //error : i 역시 블록 스코프를 지닌 변수
이렇게 var, let, const 키워드와 호이스팅에 대해서 알아봤다.
왜 let, const가 나왔고 어떤 문제점이 var에 있는지 알게 되었으니 코딩을 할 때 더 유용하게 활용할 수 있을것이다.