요즘에, var를 쓰지 말라는 사람들이 많아서, es6이후에 자바스크립트를 배운사람들은 처음보는 키워드일 수도 있고, 그냥 변수 선언 하는 키워드정도로 생각을 하는데, 왜 쓰지 말라는 지에 대해서 잘 모르는 분들이 있을 것이다.
아래의 코드들로 하여금 어느정도 해당 키워드의 나쁜점을 좀 드러 낼 수 있게 let과 비교를 하며 설명을 드리고자 한다.
몇가지 집고 아래 코드를 보도록 하자, 않그러면 코드 자체가 이해 안 될 수 있으니.
1. var, let은 스코프의 차이가 있다. var의 경우에는 function scope, let은 block scope를 가진다.
(function () {
//... function scope
{
//... block scope
var a = 1
console.log(a)
}
console.log(a)
})()
(function () {
//... function scope
{
//... block scope
let b = 1
console.log(b)
}
console.log(b) // Uncaught ReferenceError: b is not defined
})()
var의 경우에는 블록 스코프 내에서 선언이 되었지만, 해당 함수내에서는 참조 가능 한것을 볼 수 있다 var는 function scope를 갖는다.
let의 경우에는 블록 스코프 내에서 선언이 되었고, 블록에서 벗어 나자마자 참조 불가능 한것을 볼 수 있다 let은 block scope를 갖는다.
2. TDZ
(function() {
console.log(a) // undefined
var a = 1
})()
(function() {
console.log(b) // Uncaught ReferenceError: Cannot access 'b' before initialization
let b = 1
})()
(function() {
console.log(c) // Uncaught ReferenceError: c is not defined
})()
var의 경우에는 해당 함수 내의 코드 최상단으로 hoisting 되고, 해당 변수를 참조 할 수 있게 된다. <- 하지만 할당 되기 전이니 당연하게도 undefined출력이 됩니다.
let의 경우에는 해당 블록의 최상단으로 hoisting 되지만, TDZ에 걸려 있어서 참조 오류가 발생한다. 선언문후에서나 해당 변수의 값을 읽고 쓰는 것이 가능하게 되어진다.
자 이정도 알면 아래의 코드를 볼 수 있게 된다.
var는 function scope를 가지고 있기 때문에, 아래의 코드가 실행의 차이를 보인다. function에서 선언이 되는지, block에서 선언이 되는지의 차이에 의해 아래와 같이 차이가 생긴다.
(function() {
var a = 10
function test() {
console.log(a) // undefined
var a = 20
console.log(a) // 20
}
test()
console.log(a) // 10
})();
(function() {
var a = 10
if ( true ) {
console.log(a) // 10
var a = 20
console.log(a) // 20
}
console.log(a) // 20
})();
하지만, let은 block scope를 가지기 때문에, function에서 선언이 되든 block내에서 선언이 되든 결과가 같은 것을 볼 수 있다.
(function() {
let b = 10
function test() {
// console.log(b) // Cannot access 'b' before initialization
let b = 20
console.log(b) // 20
}
test()
console.log(b) // 10
})();
(function() {
let b = 10
if ( true ) {
// console.log(b) // Cannot access 'b' before initialization
let b = 20
console.log(b) // 20
}
console.log(b) // 10
})();
이 처럼 선언 된 위치의 차이의 차이가 없기 때문에 더 실수를 줄일 수 있다.
조금 더 있을 법한코드로 예제를 보자. 대부분의 개발자들이 for문의 초기값에 선언 키워드를 이용하여 선언한 변수가 for문 밖의 변수의 값에 영향을 주는 것을 불편하게 생각 할 것이라고 생각 한다.
var의 경우에는 위에서 언급 하였듯이 function scope이고, for문은 block scope이기 때문에 for문에서 초기값으로 선언 되었다고 하더라고 해당 함수에서 선언 된 것처럼 행동 한다.
(function() {
var idx = 0
//어쩌고 저쩌고 아주 긴 로직 시작
idx = 20
//어쩌고 저쩌고 아주 긴 로직 완료for ( var idx = 0 ; idx < 3 ; idx++ ) {}
console.log(idx) // 3
})();
(function() {
let idx = 0
//어쩌고 저쩌고 아주 긴 로직 시작
idx = 20
//어쩌고 저쩌고 아주 긴 로직 완료
for ( let idx = 0 ; idx < 3 ; idx++ ) {}
console.log(idx) // 20
})();
이렇듯 var의 경우에는 개발자가 예측하기가 let보다는 더 불편 하기 때문에, var는 let으로 대체가 되어왔다.
댓글
댓글 쓰기