[JS] Hoisting 호이스팅

728x90
반응형

아직 선언하지 않은 변수를 호출하더라도 undefined가 출력된다면? 이것이 바로 호이스팅

 

console.log(a); // undefined;
console.log(test);//undefined;
console.log(test2); // function test2 () {...} 저 밑에 선언한 함수가 출력된다 오잉 


var a='호이스팅'; // 호이스팅 되는 var 변수


//함수 표현식은 호이스팅 되지 않지 하지만 var test 변수는 호이스팅 된다.
var test=function(){
console.log('test');
}

//호이스팅이 되는 함수 선언문..!!
function test2(){
console.log('test2');
}

 

분명 변수를 선언하기 전에 호출 먼저 했는데도 에러가 나지않고 출력이 된다..!! 

 

위를 보면 var 변수의 선언문이나 function 선언문 등 모든 선언문이 해당 스코프의 선두로 옮겨진 것처럼

동작하는 것을 호이스팅이라고 한다.

 

그럼 호이스팅이 일어나면 우리 눈에 보이지 않지만 실제로 프로그램은 이런 식으로 동작한다

 

// 선언 부분이 끌어올려진다 (1)
var a; // 호이스팅 되는 var 변수
var test;
//호이스팅이 되는 함수 선언문..!!
function test2(){
console.log('test2');
}

(2) 출력
console.log(a); //undefined
console.log(test); //var 변수여서 에러가 나지 않고 undefined
console.log(test2); // function test2 () {...} 함수가 출력된다 오잉 


(3) 실제로 작성된 코드 위치에서 할당이 이루어진다.
a='a';
test=function(){
console.log('test');
}

 

작성한 코드 부분 중에서 선언 부분이 끌어올려지고 (여기서 스코프는 전역 스코프)

함수 선언문은 전체가 호이스팅되며 함수 표현식 test 함수는 변수의 선언과 할당이 구분되어 할당은 밑에 남는다.

 

여기서 test함수는 var로 선언했기에 console.log(test)에서 undefined로 출력되지만 let, const의 경우에는 오류가 난다

 

console.log(test); // "ReferenceError: Cannot access 'test' before initialization

let test=function(){
console.log('test');
}

 

이렇게 같은 함수 표현식을 let으로 선언했더니 초기화되기 전에 접근할 수 없다는 참조 에러가 난다.

 

이는 JS의 변수의 생성과 관련이 있는데 변수는 크게 3단계를 거쳐 생성이 된다.

 

1) 선언 단계 : 변수 객체에 변수를 등록해 스코프가 참조하는 대상이 됨

2) 초기화 단계 : 변수 객체에 등록한 변수를 실제 메모리에 할당, 여기서 undefined로 초기화 됨

3) 할당 단계 : 실제 값을 할당 

 

왜 변수 생성과 관련이 있다는 걸까? 

var 변수는 선언과 초기화 단계가 같이 이루어지고

let,const (es6문법)에서는 선언과 초기화 단계가 별개로 이루어지기 때문이다. 

즉 var 변수는 undefined로의 초기화 단계까지 이루어지지만 let, const는 그렇지 않다.

 

따라서 let, const 변수의 경우 선언과 초기화 단계 사이의 TDZ (Temporal Dead Zone)가 생긴다.

임시적 사각 지대라고도 불린다.

 

let test;
console.log(test); // "ReferenceError: Cannot access 'test' before initialization

test=function(){
console.log('test');
}

위의 코드를 호이스팅 된 모습을 보면 이럴 것이다. test는 선언 단계만 거쳐서 undefind로 초기화되지 않은 상태에서 

참조되어 에러를 뱉어낸다 (TDZ 구간이기 때문에)

 

 

사담: 

처음에는 호이스팅 정말 어려웠는데 계속 보다보니 익숙해져서 이해가 되었다. 

스코프 부분이 안된다면 (스코프의 상단으로 호이스팅 된다는 부분) 스코프를 공부하면 될 것이다.

var, let, const 비교 내용에도 기술하면 좋을 듯 하다.

 

 

출처:

밑은 호이스팅 함수 예제를 참고했다. 위의 변수 생성 부분은 다른 글을 보고 노션에 적었던 걸 다시 정리했는데 원출처가 어딘지 기재가 안되어있어 한 번 찾아봐야겠다 ㅠㅠ 

perfectacle.github.io/2017/04/26/js-002-hoisting/

728x90
반응형
TAGS.

Comments