호이스팅

GJ·2023년 5월 8일
0

프론트엔드지식

목록 보기
3/14

호이스팅(Hoisting)은 자바스크립트에서 변수와 함수 선언이 해당 스코프의 최상위로 끌어올리는 것을 말한다.
호이스팅을 통해 코드의 위치와 상관없이 변수나 함수를 선언하기 전에도 참조 될 수 있다.

호이스팅은 두 가지 단계로 진행된다.

  1. 스코프 내의 변수와 함수 선언을 찾는다.
  2. 해당 변수와 함수 선언을 스코프 상단으로 이동한다.

변수 호이스팅(Variable Hoisting)

변수 선언은 스코프 내부의 상단으로 끌어올려진다.
변수 선언은 끌어올려지지만, 변수의 할당은 끌어올려지지 않는다.
따라서 변수를 사용하기 전에 변수를 할당해야 한다.

console.log(a); // undefined
var a = 10;

위 코드에서 변수 a의 선언은 console.log(a) 코드 위로 끌어올려지지만, 변수의 초기값은 끌어올려지지 않아 a의 값은 undefined이다.

let으로 변수를 선언한다면, 변수가 선언된 라인 이전에 변수에 접근하면 해당 변수는 정의되지 않았다는 에러가 발생한다.
이는 변수가 호이스팅되어 메모리 공간이 할당되지만, 초기화되지 않기 때문이다.
예를 들어, 다음과 같은 코드를 작성하면 ReferenceError가 발생한다.

console.log(x); // ReferenceError: Cannot access 'x' before initialization
let x = 1;

하지만 let으로 변수를 선언하고, 변수를 초기화한 후에 해당 변수를 참조하면 정상적으로 동작한다.

let x;
console.log(x); // undefined
x = 1;
console.log(x); // 1

따라서 let으로 변수를 선언할 때에는 변수를 선언한 후, 변수를 사용해야 한다.

함수 호이스팅(Function Hoisting)

함수 선언도 변수와 마찬가지로 스코프 내부의 상단으로 끌어올려진다.
함수 선언은 변수 선언이나 함수 표현식과는 달리, 함수의 이름과 함수 코드가 함께 끌어올려진다.
따라서 함수가 코드에서 선언되기 이전 단락에서 함수를 호출할 수 있다.

foo(); // "Hello, world!"

function foo() {
  console.log("Hello, world!");
}

위 코드에서 함수 foo의 선언은 foo() 코드 위로 끌어올려지기 때문에, 함수를 호출하기 전에 함수를 선언할 수 있다.

하지만 함수 표현식을 사용하는 경우에는, 함수 이름을 제외한 함수 표현식의 내용은 호이스팅되지 않는다.

foo(); // Error: foo is not a function

var foo = function() {
  console.log("Hello, world!");
}

위 코드에서 함수 표현식 foo는 변수 foo에 할당되기 때문에, 변수 선언은 호이스팅되지만, 함수 내용은 호이스팅되지 않는다.
따라서, 변수 foo에 함수가 할당되기 전에 함수를 호출하면 에러가 발생한다.

결론

변수는 항상 호이스팅 되지만 실제 할당 전에 참조하려고 하면,
var으로 선언된 변수는 undefined로 참조되고,
let으로 선언된 변수는 아예 에러가 발생한다.

함수선언문의 경우는 실제 정의와 함께 호이스팅 된다.
다만, 함수표현식의 경우는 실제로는 변수이므로 실제 할당 전에 참조하려고 하면 undefined가 되고, 함수로 사용하려고 하면 당연히 함수가 아니라며 에러가 발생한다.

profile
Frontend Developer

0개의 댓글