민규의 개발블로그
자바스크립트 호이스팅 본문
호이스팅에 대해 설명하기 앞서서 아래 코드의 결과는 무엇 일가??
결괏값이 undefined라 예상하는 사람도 있겠지만 정답은 2다. 이유는 아래에서 설명하겠다.
자바스크립트 엔진은 코드를 인터프리팅하기 전에 컴파일한다. 컴파일레이션 단계 중에는 모든 선언문을 찾아 적절한 스코프에 연결해주는 과정이 있는데(렉시컬 스코프의 핵심) 변수와 함수 선언문 모두 코드가 실제 실행되기 전에 먼저
처리된다고 보면 된다.
var a; // 선언문
a = 2; // 대입문
첫째 구문은 선언문으로 컴파일레이션 단계에서 처리된다. 둘째 구문은 대입문으로 실행 단계까지 내버려둔다.
따라서 아까 위의 코드는 이렇게 실행된다. 이 과정을 비유적으로 말하면 변수와 함수 선언문은 선언된 위치에서 코드의 꼭대기로 '끌어올려' 진다. 이렇게 선언문을 끌어올리는 동작을 '호이스팅' 이라고 한다.
선언문만 끌어올려지고 다른 대입문이나 실행 로직 부분은 제자리에 그대로 둔다. 호이스팅으로 코드 실행 로직 부분이 재배치된다면 큰 혼란이 생길 수 있음.
함수 선언문도 끌어 올려지지만 함수 표현식은 다르다.
변수 확인자 foo는 끌어올려져 둘러싼 글로벌 스코프에 붙으므로 foo ( ) 호출은 실패하지않고, ReferenceError도 발생하지 않는다. 그러나 foo는 아직 값을 가지고 있지 않는데 foo( )가 undefined 값을 호출하려 해서 TypeError라는 오작동을 발생시킨다.
함수와 변수 선언문은 모두 끌어올려진다. 그러나 먼저 함수가 끌어올려지고 다음으로 변수가 올려진다.
아래 코드는 결괏값으로 2가 아니라 1이 출력된다. 엔진은 이 코드를 다음과 같이 해석한다.
해석 -----
function foo( ){
console.log(1);
}
foo( ); // 1
foo = function( ){
console.log(2);
};
결론
스코프의 모든 선어문은 어디서 나타나든 실행 전에 먼저 처리된다. '호이스팅'이라 불리는 이 과정은 선언문 각각이 속한 스코프의 꼭대기로 끌어올려지는 작업이라고 생각할 수 있다. 그 과정에서 선언문 자체는 옮겨지지만, 함수 표현식의 대입문을 포함한 모든 대입문은 끌어올려 지지 않는다.
중복 선언을 조심하자. 일반 변수 선언과 함수 선언을 섞어 사용하면 특히 더 위험하다.
'Javascript' 카테고리의 다른 글
자바스크립트 렉시컬 스코프 (0) | 2020.11.20 |
---|---|
자바스크립트 스코프 (0) | 2020.11.20 |
자바스크립트 문법 (0) | 2020.11.19 |
자바스크립트 강제변환-2 (0) | 2020.11.17 |
자바스크립트 강제변환-1 (0) | 2020.11.16 |