본문 바로가기
javascript

호이스팅(Hoisting)

by hjcode 2019. 9. 26.

var 변수의 의도치 않은 현상

if(true){
	var name = 'hj';
}

console.log(name); //hj

for(var i=0; i<5; i++){

}
console.log(i) //5

일반적인 프로그래밍 언어에서 변수는 블록 스코프{ } 안에서 유효하기 때문에, 블록이 종료된 시점에서 console.log를 호출하면 정상적으로 동작하지 않을거라고 생각됩니다.

하지만 ‘hj’과 ‘5’가 콘솔에 출력되는 것을 볼 수 있습니다. 이러한 현상은 var 변수가 호이스팅 되기 때문에 발생합니다.

호이스팅(Hoisting)

호이스팅은 var을 통해 정의된 변수의 선언문을 유효 범위의 최상단으로 끌어올리는 행위를 말합니다.

‘선언과 할당의 분리’라고 생각하면 기억하기 좋을 것 같습니다.

 

사용자가 작성한 코드

if(true){
  var name = 'hj';
}
console.log(name);

호이스팅으로 변환된 코드

var name; // 선언
if(true){
  name = 'hj'; // 할당
}
console.log(name);

 

var의 유효범위

호이스팅시 선언문은 유효 범위의 최상단으로 올라간다고 했습니다.

자바스크립트의 var는 단순한 블록{ }이 아닌 함수 블록function{ } 안에서 유효합니다.

이를 var는 함수 스코프에서 유효하다 라고 합니다.

 

사용자가 작성한 코드

function ho1(){
  if(true){
    var name = 'hj';
  }
  console.log(name);
}

function ho2(){
  for(var i=0; i<5; i++){
    // do something
  }
  console.log(i);
}

if(true){
  var score = 100;
}
console.log(score);

호이스팅으로 변환된 코드

var score; // 선언

function ho1(){
  var name; // 선언

  if(true){
    name = 'yuddomack'; // 할당
  }
  console.log(name);
}

function ho2(){
  var i; // 선언

  for(i=0; i<5; i++){ // 할당
    // do something
  }
  console.log(i);
}

if(true){
  score = 100; // 할당
}
console.log(score);

var는 함수 스코프에서 유효하기 때문에 호이스팅 시, 선언문은 글로벌 스코프가 아닌

유효범위(함수) 내부의 최상단에 위치하게 됩니다.

글로벌 스코프 또한 하나의 함수 스코프 처럼 동작하기 때문에 호이스팅이 일어납니다.

함수 호이스팅

함수의 선언 역시 호이스팅의 대상입니다.

때문에 스코프 내에서 어떤 위치에서 함수 선언을 하든지 호출할 수 있습니다.

 

사용자가 작성한 코드

sayName();

function sayName(){
  console.log('hj');
}

호이스팅으로 변환된 코드

function sayName(){
  console.log('hj');
}

sayName();

함수 선언 역시 최상단으로 끌어올려지기 때문에 sayName()을 먼저 호출하고

함수 정의를 이후에 하여도 정상적으로 동작하게 됩니다.

그렇다면 아래의 경우는 어떨까요?

sayName();

var sayName = function(){
  console.log('hj');
}

선언 방식이 약간 다르지만, 두 방식 모두 함수를 선언한 것 입니다.

function sayName(){}는 함수 선언식,

var sayName = function(){}은 함수 표현식 이라고 합니다.

글을 계속 읽기 전에 잠시만 결과를 예상해 보실까요?

어떤 결과를 예상하셨을지 모르겠지만 에러가 발생하게 됩니다.

var sayName;

sayName();

sayName = function(){
  console.log('hj');
}

var sayName은 변수이기 때문이죠. 그렇기에 ‘선언과 할당’의 분리가 발생합니다.

순서를 보자면 sayName이 선언되고 sayName()이 호출되지만 거기엔 아무것도 없습니다.

그 이후에 sayName에 함수가 정의되는 것이지요.

반응형

'javascript' 카테고리의 다른 글

스크롤했을때 나타나는 이미지  (0) 2019.09.26
스코프(Scope)  (0) 2019.09.26
로또 추첨 만들기  (0) 2019.09.26
javascript 끝말잇기  (0) 2019.09.26
삼항 조건 연산자  (0) 2019.09.25