var, let , const 의 차이점을 알아보자..!
var는 function scoped 이고 let, const는 block-scoped 이다.
변수의 범위와, hoisting 범위 모두 function
for (var i=0; i<10; i++){
console.log('i', i)
}
console.log('after loop i', i) // 10예시1 에서는 i가 function scoped 이기 때문에 loop가 끝난 후 i를 호출하면 출력이 잘 된다.
function example(){
for (var i=0; i<10; i++){
console.log('i', i)
}
}
example()
console.log('after loop i', i) // Reference Error: i is not defined예시2 에서는 function scoped 밖에서 호출해서 에러가 뜬다.
위와 같은 방법을 이용해서.. 예전에는 이렇게 변수 관리를 했다고 한다.
var gVariable = (function(name){
for (var i=0; i<10; i++){
console.log('i', i)
}
console.log(name) // 'kim'
})('kim')
console.log('after loop i', i) // Reference Error: i is not defined즉시 실행 함수를 이용하여 함수 내부의 변수를 priavte화 하고 ( scope가 function 이니까!) gVariable 는 전역변수로 사용했다고 한다.
단 여기서도 알아둬야 할 점이 있다.
var i
(function(name){
for (i=0; i<10; i++){
console.log('i', i)
}
console.log(name) // 'kim'
})('kim')
console.log('after loop i', i) // after loop i 10예시2 에서 var 키워드를 뺀다면 위와 같이 i 가 hoisting 되어 global variable이 된다.
예전에는 이를 막기위해 아래와 같은 방법을 썻다고 한다.
(function(name){
'use strict'
for (i=0; i<10; i++){
console.log('i', i)
}
console.log(name) // 'kim'
})('kim')
console.log('after loop i', i) // Reference Erroruse strict 를 사용하여 i변수가 hoisting 되는 것을 막는다. use strict는 이처럼 hoisting을 막기도 하고, this 가 window 객체를 가리키지 못하게 한다.
변수의 범위와, hoisting 범위 모두 blocked
let 과 const 는 blocked scoped 이다. let과 const의 차이는 변수의 immutalbe 여부이다. let은 변수에 재할당이 가능하지만, const 는 변수 재선언, 재할당 모두 불가능하다.
위에서 사용했던 예시1을 비교해 보면,
for (let i=0; i<10; i++){
console.log('i', i)
}
console.log('after loop i', i) // Reference Errori가 blocked scoped 이기 때문에 참조 에러가 발생한다.
다른예시.
for (var i=0; i<10; i++){
setTimeout(function(){console.log(i)}, 3000)
}위와 같은 코드를 실행하면 i가 10으로 10번 출력된다. 그 이유는 for문이 끝나는 시점의 i 변수는 var로 선언 되었기 때문에 function scoped를 갖게 되고 해당 시점의 i값은 10이기 때문이다.
선언을 let으로 한다면,
for (let i=0; i<10; i++){
setTimeout(function(){console.log(i)}, 3000)
}자바스크립트 엔진이 실행될 때 블록이 10개 생기고 각 블록의 i 값을 참조하기 때문에 올바르게 원하는 값을 출력 할 수 있다.
위에서 정리한 즉시실행함수(IIFE)를 이용
for (var i=0; i<10; i++){
(function(count){
setTimeout(function(){
console.log(count)
},3000)
})(i)
}var는 중복 선언을 허용한다
let 과 const는 중복 선언을 허용하지 않는다.
var a = 1
var a = 2 // okay
let b = 1
let b = 2 // Nooo var는 변수의 선언과 동시에 undefined로 초기화가 된다.let은 변수 선언 이전에 참조를 하면 Reference Error가 발생한다. 선언과 동시에 undefined로 초기화 되는 var와 다르게 let은 선언만 되고 대입 연산자를 만날 때 까지 값이 없다. 따라서 값이 할당 되기 전까지 참조를 하게 되면 Reference Error를 발생하게 되고 이 구간을 TDZ(temporal dead zone) 이라고 한다.console.log(a) // undefined
var a = 'hi'a 변수가 hoisting 되어 scope 상단에 선언과 동시에 undefined로 초기화 되었기 때문에 오류가 발생하지 않는다.
console.log(b) // Uncaught ReferenceError: b is not defined
let b = 'hi'b 변수가 hoisting 되어 scope 상단에 선언 되겠지만, 값이 초기화 되지 않기 때문에 참조하려고 하면 에러를 발생시킨다.
const는 선언과 동시에 초기화 해줘야 한다!