on
[Javascript]호이스팅(Hoisting)
자바스크립트의 첫 관문이랄까…
자바스크립트는 왜 이러는 걸까?
일반적으로 프로그래밍은 특별한 상황이 아닌 이상, 코드를 한줄씩 아래로 읽어가며 실행하는 방식으로 진행된다. 그렇다면 아래 예제의 결과는 어떻게 나올까?
console.log(human);
var human;
hoxy….Error
라고 생각한 당신….?
C언어나 다른 프로그래밍 언어에서, 아직 선언하지 않은 human을 참조하는 코드가 먼저 있다면 당연히 에러를 뿜을 것이다. 하지만 놀랍게도 자바스크립트에서 위 예제는 에러가 아니다!!!!
실행 결과는 아래와 같다.
console.log(human); //undefined
var human;
그렇다. console
의 결과는 undefined
다. 자바스크립트로 프로그래밍을 먼저 시작한 사람은 그러려니 할 수도 있겠으나, 다른 언어로 프로그래밍을 먼저 공부한 사람은 여기서 한번 자바스크립트의 문턱에 맞딱드린다.(자바스크립트가 근본이 없다고 말하게 되는 한가지 포인트…)
1. 소스 코드 평가와 호이스팅
결론부터 말하자면, 자바스크립트가 코드가 위에서 아래로 착착착 실행되는 런타임 이전에, 변수 선언문과 함수 선언문들만 모아서 선언을 먼저 하고 난 뒤, 런타임이 진행되기 때문이다.
//코드 순서
console.log(human); //(1)
let human; //(2)
console.log(human, "사람"); //(3)
//실행되는 순서
let humamn; // (1)
console.log(human); //(2)
console.log(human, "사람"); //(3)
풀어서 얘기해보자면,
자바스크립트는 코드를 순차적으로 실행하기에 앞서 먼저 소스 코드 평가 과정을 거친다. 그 평가과정에서 소스코드를 실행하기 위한 준비를 하는데, 이때 모든 선언문을 찾아내 먼저 실행한다(호이스팅). 그 이후 선언문을 제외한 소스코드를 한 줄씩 순차적으로 실행하는 것이다.
hoisting: 끌어올리다 모든 선언문을 코드 가장 상단으로 끌어 올린다고 생각하면 쉽겠다.
따라서 자바스크립트에서는 소스 코드에 선언된 변수의 위치와 상관없이 어디서든 변수를 참조할 수 있다.
호이스팅은 변수는 물론 함수도 가능하다.
2. 단축 표현
var phoneNumber; //선언
phoneNumber = "010-1234-4567"; //할당
var phoneNumber = "010-1234-4567"; //단축표현
단축 표현을 사용하더라도 실제 자바스크립트 엔진은 두개의 문으로 나눠서 실행하므로 실행 순서는 같다. 따라서 하나의 단축 표현으로 코드를 작성해도, 호이스팅이 일어나기 때문에 변수의 선언은 미리 일어나지만, 할당은 순차적으로 일어난다.
//코드
console.log(phoneNumber); //undefined
let phoneNumber = "010-1234-5678";
console.log(phoneNumber); //"010-1234-5678"
//실행 순서
let phoneNumber; // undefined 할당 됨
console.log(phoneNumber);
phoneNumber = "010-1234-5678";
console.log(phoneNumber);
3. ES6와 호이스팅
요새는 그런 주장이 많이 없지만, 예전엔 ES6
의 변수 키워드인 let
이나 const
는 호이스팅이 되지 않는다는 이야기가 있었다. 지금은 많은 현자 개발자분들께서 그것이 왜 틀린 주장인지 여기저기 설파하고 다녀주셔서(?) ES6
와 상관없이 모든 선언은 호이스팅 된다는게 정설이 되었다. 이부분은 증명하기 위해선 TDZ:Temporal Dead Zone
와 연관지어 보아야 함으로, 추후에 TDZ
와 관련된 포스팅 후 링크를 남기도록 하겠다.
(TDZ 알아보기)