# var, let, const 그리고 호이스팅

```javascript
console.log(a)

var a = 'apple'
```

위 코드를 실행하면 `undefined`라는 결과가 출력된다. 어떻게 된 일일까?

자바스크립트 엔진은 변수 선언이 코드의 어디에 있던 상관 없이 다른 코드보다 먼저 실행된다. 코드를 위에서 아래로 쭉 실행하기 전, 변수와 함수 선언문 등을 소스코드에서 찾아서 실행한다. 이때 변수를 저장할 메모리 공간을 미리 확보하여 `undefined`라는 값이 암묵적으로 할당되어 초기화된다. 그리고 이런 평가 과정이 끝나면 모든 선언문을 제외하고 위에서부터 한 줄 씩 실행한다.

이처럼 선언문이 코드의 선두로 끌어 올려진 것처럼 동작하는 자바스크립트 고유의 특징을 **호이스팅**이라고 한다. var, let, const, function, class 키워드를 사용해서 선언하는 모든 식별자는 호이스팅된다.

그렇다면 ES6에서 사용되는 변수 선언문인 let과 const가 동작하는 방식을 알아보자.

```javascript
console.log(b)

let b = 'banana'
```

위 코드를 실행하면 `undefined`가 출력될까? 정답은 NO!

let은 var과 달리 변수를 저장할 메모리 공간을 미리 확보하지 않아 값이 `undefined`로 초기화되지 않는다. 대신 코드를 위에서 아래로 실행할 때 변수 선언문에 도달하면 초기화 단계를 맞이하게 된다. 이러한 이유로 초기화 이전에 변수에 접근하면 **참조 에러(Reference Error)**가 발생한다.

const는 재할당과 재선언이 불가능하기 때문에 선언과 할당을 동시에 진행해야 한다. 만약 선언 이전에 변수에 접근하거나 이미 선언된 변수에 다른 값을 할당한다면 **참조 에러**가 발생한다.
