- 자바스크립트는 언어 특성상 코드의 제일 윗줄부터 한 줄씩 차례대로 읽고 실행시킵니다.
- 따라서 위 코드의 2번째 줄 console.log(a)에서 변수 a는 아직 선언되지 않았기 때문에 ‘a is not defined’라는 오류가 나와야합니다.
- 하지만! Hoisting이라는 특징 덕분에 자바스크립트가 실행되자마자 변수 a의 선언부분이 자신이 속한 Scope의 제일 윗부분(1번째 줄)으로 끌어올려지게 됩니다. 따라서 2번째 줄이 실행될 때는 이미 밑에 변수 a가 존재한다는 사실을 알게됩니다. 하지만 선언부분만 Hoisting이 된 것일뿐 아직 변수 a의 값이 초기화되지 않아 2번째 줄의 실행 결과는 undefined가 출력됩니다.
※ Hoisting이 일어나면 변수 선언 부분이 제일 위로 끌어올려져서 실행된다고 생각합시다. 다만 주의할 점은 실제 작동시 변수 선언 부분이 Scope의 가장 윗쪽에 생성되어 실행되는 것은 아닙니다!
- 위 코드를 보면 2번째 줄에서 변수 a가 선언됨과 동시에 값 1로 초기화 되었고 2번째 줄에서 바로 foo 함수를 실행시킵니다.
- 하지만, foo 함수는 4번째 줄에서 처음으로 정의되기 때문에 3번째 줄에서는 아직 foo함수를 알지 못해야합니다.
- 그렇지만 Hoisting 때문에 foo함수의 선언부분이 Scope의 가장 윗쪽(1번째 줄)으로 끌어올려져 3번째 줄에서 foo함수의 존재를 알기 때문에 실행이 가능합니다.
- 2번째 줄에서 bar 함수를 호출했기 때문에 3번째 줄을 실행하지 않고 바로 bar 함수의 내부코드가 실행이 됩니다.
- 그리고 10번째 줄을 실행시킬 때, 변수 b는 아직 선언되어 있지 않았지만 Hoisting이 일어나 변수 b의 선언부분이 끌어올려졌고 10번째 줄의 console.log(b)에서 변수 b의 존재는 알지만 아직 값이 초기화되어 있는 상태가 아니기 때문에 값을 알 수가 없어 undefined가 출력됩니다.
- bar 함수가 종료되면 b = 1로 초기화됩니다. 따라서 13번째 줄에서 b = 1이라는 결과가 출력됩니다.
☞ 함수 표현식으로 함수 작성시 주의할 점을 알려드리겠습니다.
- 2번째 줄이 실행되면 에러가 발생합니다. 왜 그럴까요?
- 변수 d는 3번째 줄에서 선언 및 초기화가 이루어집니다. 하지만 Hoisting이 일어나기 때문에 2번째 줄에서는 이미 변수 d의 존재를 알고 있습니다. 다만 아직 초기화가 이루어지지 않은 상태이기 때문에 값을 알 수는 없습니다.
- 따라서 ‘d is not a function’ 이라는 에러 문구가 출력되고 함수는 실행되지 않습니다.
※ 함수 표현식으로 함수를 작성하고 실행시킬 때는 항상 Hoisting의 문제를 조심해야 합니다. 왜냐하면 함수가 변수에 대입이 된 이후에 실행시킬 수 있기 때문입니다.