1 분 소요

호이스팅

호이스팅(Hoisting)은 자바스크립트에서 변수와 함수 선언이 유효 범위(scope) 상단으로 끌어올려지는 현상을 의미합니다. 즉, 코드에서 변수나 함수 선언문이 실제 위치보다 먼저 호출되어도, 선언문이 유효 범위 상단으로 끌어올려져서 실행되는 현상입니다.

console.log(undeclared);	// Uncaught ReferenceError: undeclared is not defined
console.log(funcTest()); // funcTest
console.log(varTest()); // Uncaught TypeError: varTest is not a function
console.log(letTest()); // Uncaught ReferenceError: letTest is not defined
console.log(constTest()); // Uncaught ReferenceError: constTest is not defined

function funcTest() {
  return "funcTest";
}

var varTest = function () {
  return "varTest";
};

let letTest = function () {
  return "letTest";
};

const constTest = function () {
  return "constTest";
};

함수에는 두 가지 리터럴 형태가 있습니다.

  1. 함수 선언 : function 키워드 뒤로 함수의 이름을 적어서 사용합니다.

    function test() {
    	return "test";
    }
    
  2. 함수 표현식 : function 키워드 뒤로 이름을 적지 않고 사용합니다. 이름이 없기 때문에 익명 함수라고 부르기도 합니다.

    let testValue = function() {
    	return "testValue";
    }
    

함수 선언은 코드를 실행할 때 함수를 포함하는 스코프 최상단으로 끌어올려집니다.

그래서 함수 선언 전에 함수를 실행해도 에러가 발생하지 않습니다.

그에 반해 함수 표현식은 변수를 통해서 함수를 참조하기 때문에 호이스팅이 일어나지 않습니다.

선언하지 않은 변수는 당연히 에러가 납니다. 하지만 선언한 변수도 ‘값’까지 끌어올려지지는 않습니다.

변수는 함수와 달리 선언만 끌어올려진다는 점에 주의합시다!

console.log(test());	// "test hoist"
console.log(value);	// Uncaught ReferenceError: value is not defined

function test() {
    var value = "hoist";
    return value + "test";
}

변수 선언 역시 코드를 실행할 때 변수를 포함하는 스코프 최상단으로 끌어올려집니다. 함수 안에 선언된 변수는 함수 스코프 안에서 최상단으로 끌어올려집니다.

호이스팅 되지 않는 선언들

let, const, class

console.log(test1);	// Uncaught ReferenceError: test1 is not defined
console.log(test2);	// Uncaught ReferenceError: test2 is not defined
console.log(Tester);	// Uncaught ReferenceError: Tester is not defined

let test1 = "let value";
const test2 = "const value";

class Tester {
    constructor() {
        this.name = "tester name";
    }
}

let tester = new Tester();

블록 스코프를 생성하는 let, const는 호이스팅이 일어나지 않습니다. class 또한 마찬가지 입니다. var로 선언된 변수는 호이스팅되지만 let, const로 선언된 변수와 상수는 TDZ(Temporal Dead Zone. 임시 접근 불가구역)에 배치됩니다. 이 값들은 선언이 실행된 후에 TDZ에서 제거되어 사용 가능한 상태가 됩니다.

댓글남기기