호이스팅에 대해 알아보자.

이말감·2022년 2월 23일
0

알아보자

목록 보기
1/2

호이스팅(Hoisting)

호이스팅이란?

: 호이스팅은 함수 안에 있는 선언들을 모두 끌어 올려서 해당 함수 유효 범위의 최상단에 선언하는 것

위의 그림으로 블로그 글을 이해했다.
① 함수는 {} 로 감싸져 있고, 이 함수 블록 내에서 유효하다.
② 자바스크립트 Parser가 함수 실행 전 해당 함수를 슥 훑고 함수 내 변수/함수 선언에 대한 정보를 기억한다.
③ 해당 변수/함수를 언급할 때 실행한다.

  • 함수 내에서 아래쪽에 존재하는 내용 중 필요한 값들을 끌어올리는 것

호이스팅의 대상

  • 호이스팅은 var 변수 선언과 함수선언문에서만 일어난다.
    • var 변수/함수의 선언만 위로 끌어올림. 할당은 X
    • let/const 변수 선언과 함수표현식에서는 호이스팅 발생 X
var apple; // 호이스팅 -> 선언
apple = "red"; // 할당
let peach = "pink"; // 호이스팅 X (let 변수)
  • 함수선언문, 함수표현식 예시
foo();
foo2();
function foo() { } // 함수선언문
var foo2 = function() { } // 함수표현식
  • 호이스팅
var foo2; // 호이스팅 -> 함수표현식의 변수값 선언
function foo() { } // 호이스팅 -> 함수선언문
foo();
foo2(); // error -> foo2가 상단에서 변수로 선언되어 호이스팅 되었기 때문에 함수가 아니다.
foo2 = function() { }

-> 선언된 변수에 할당된 함수표현식은 끌어올려지지 않으므로 변수의 스코프 규칙을 따른다.

함수선언문, 함수표현식의 호이스팅

함수선언문에서의 호이스팅

  • 함수선언문은 코드를 구현한 위치와 관계없이 호이스팅에 따라 브라우저가 자바스크립트를 해석할 때 맨 위로 끌어 올려진다.
function printName() {
  var result = inner(); // 선언 및 할당
  console.log(typeof inner); // "function"
  console.log(result); // "inner value"
  
  function inner() {
    return "inner value";
  }
}

printName();

-> inner 함수가 할당되고 해당 값을 콘솔에 출력하는 부분보다 더 아래있지만, js의 parser가 슥 돌아본 후 inner()라는 함수를 기억한 덕분에 자바스크립트를 해석할 때 오류없이 사용되었다.

  • 함수선언문이 위에 있든, 아래에 있든 함수 내에서 inner를 function으로 인식하기 때문에 오류가 발생하지 않는다.

함수표현식에서의 호이스팅

  • 함수표현식은 함수선언문과 달리 선언과 호출 순서에 따라서 정상적으로 함수가 실행되지 않을 수 있다.
    • 함수표현식에서는 선언과 할당의 분리가 발생

1. 함수표현식의 선언이 호출보다 위에 있는 경우 (정상 출력)

function printName() { // 함수선언문
  var inner = function() { // 함수표현식
    return "inner";
  }
  var result = inner(); // 함수 호출
  console.log(result); // "inner"
}

printName();
function printName() { // 함수선언문
  var inner; // 호이스팅 - 함수표현식의 변수값 선언
  var result; // 호이스팅 - 변수 선언
  
  inner = function() { // 함수표현식 할당
    return "inner";
  }
  
  result = inner();
  console.log(result); // "inner"
}

printName();

2. 함수표현식의 선언이 호출보다 아래에 있는 경우 - var (에러 발생)

function printName() { // 함수선언문
  console.log(inner);  // undefined -> 선언은 되어있지만, 할당이 되지 않은 경우
  var result = inner(); 
  // error -> 함수가 실행되면서 inner가 함수로 인식되지 않아 undefined로 지정되는데, 
  // undefined에 함수를 할당하고 있기 때문에 에러 발생
  console.log(result); 
  var inner = function() { // 함수표현식
    return "inner";
  }
}

printName();
function printName() { // 함수선언문
  var inner; // 호이스팅 - 함수표현식의 변수값 선언
  
  console.log(inner); // undefined
  var result = inner(); // error
  // inner는 이미 선언은 되었지만 할당되지 않은 상태라 undefined 값을 가지고 있기 때문에 함수로 인식 X
  console.log(result); // "inner"
  inner = function() { // 함수표현식 할당
    return "inner";
  }
}

printName();

2. 함수표현식의 선언이 호출보다 아래에 있는 경우 - var (에러 발생)

function printName() { // 함수선언문
  console.log(inner);  // undefined -> 선언은 되어있지만, 할당이 되지 않은 경우
  var result = inner(); 
  // error -> 함수가 실행되면서 inner가 함수로 인식되지 않아 undefined로 지정되는데, 
  // undefined에 함수를 할당하고 있기 때문에 에러 발생
  console.log(result); 
  var inner = function() { // 함수표현식
    return "inner";
  }
}

printName(); // inner is not a function 에러 발생
function printName() { // 함수선언문
  var inner; // 호이스팅 - 함수표현식의 변수값 선언
  
  console.log(inner); // undefined
  var result = inner(); // error
  // inner는 이미 선언은 되었지만 할당되지 않은 상태라 undefined 값을 가지고 있기 때문에 함수로 인식 X
  console.log(result); // "inner"
  inner = function() { // 함수표현식 할당
    return "inner";
  }
}

printName(); // inner is not a function 에러 발생
  • 호이스팅으로 인해 inner가 함수가 아니라는 에러가 발생한다.

3. 함수표현식의 선언이 호출보다 아래에 있는 경우 - const/let (에러 발생)

function printName() { // 함수선언문
  console.log(inner);  // error -> inner 함수가 let으로 선언되었기 때문에 호이스팅 X ->  에러 발생
  var result = inner(); 
  console.log(result); 
  let inner = function() { // 함수표현식
    return "inner";
  }
}printName(); // inner is not defined 에러 발생
  • let/const로 선언된 함수는 호이스팅이 발생하지 않으므로 console.log(inner) 부분에서 inner에 대한 선언이 되지 않았다고 판단하여 inner가 정의되지 않았다는 에러가 발생한다.

호이스팅 우선순위

변수 선언이 함수 선언보다 위로 끌어올려짐

var myName; // 호이스팅 - 변수값 선언 
var yourName;

function myName() {} // 호이스팅 - 함수선언문
function yourName() {}

myName = "hi"; // 변수값 할당
yourName = "bye";

console.log(type myName); // string
console.log(type yourName); // string

값이 할당되어 있지 않은 변수와 값이 할당되어 있는 변수에서의 호이스팅

var myName = "Hi"; // 값 할당 
var yourName; // 값 할당 X

function myName() {} // 같은 이름의 함수 선언
function yourName() {} // 같은 이름의 함수 선언

console.log(type myName); // string
console.log(type yourName); // function
  • 값이 할당되어 있지 않은 변수의 경우, 함수선언문이 변수를 덮어쓴다.
  • 값이 할당되어 있는 변수의 경우, 변수가 함수선언문을 덮어쓴다.

호이스팅 요약

호이스팅이란?

  • 호이스팅은 함수 안에 있는 선언들을 모두 끌어 올려서 해당 함수 유효 범위의 최상단에 선언하는 것

호이스팅이 발생하는 경우?

  • var 변수/함수를 사용하는 경우
  • 함수선언문을 사용하는 경우

호이스팅 방지 방법

  • 함수와 변수를 코드 상단부에서 선언하기
  • let/const 사용
profile
전 척척학사지만 말하는 감자에요

0개의 댓글